我正在尝试使用CMT设置网络应用程序 . 我已经让它在Eclipse中独立运行了,现在我正在尝试使用Struts 1.0在Jboss AS 6中运行它 . 我选择了CMT,因为我读过的doco暗示它是最好的和“使用最不详细” . 所以看起来像Hibernate 3.6的现代/良好实践使用 .
我可以使用以下代码提取从MySQL数据库加载对象,但持久化对象不会被刷新/同步/保存到数据库:
从Struts 1.0 Action类中:
InitialContext ctx = new InitialContext();
EntityManagerFactory emf = (EntityManagerFactory)ctx.lookup("java:/MyEntityManagerFactory");
然后将'emf'传递给我的DAO类的方法,总结如下:
@PersistenceContext(unitName="purejetJPA") EntityManager em;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
exampleMethodInMyCustomDAOClass() {
EntityManager em = emf.createEntityManager();
em.find(MyCustomEntity.class, 542); // works successfully
em.persist(newInstanceOfMyCustomEntity); // this executes ok and generates an ID
// however the entity is not saved to database upon completion
}
persistence.xml的内容:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="myPersistanceUnitName" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/MySqlDS</jta-data-source>
<class>my.custom.entity.Classes</class>
<properties>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/MyEntityManagerFactory"/>
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.connection.autocommit" value="false"/>
<property name="hibernate.current_session_context_class" value="jta"/>
</properties>
</persistence-unit>
</persistence>
Hibernate EntityManager文档对如何实现CMT的描述非常有限:
我们用于CMT和EJB3容器使用的实体管理器/事务管理习惯用法简化为:// CMT习语通过注入@PersistenceContext(name =“sample”)EntityManager em;
而且这个jboss.org article说:
Transaction demarcation with EJB/CMT
我们的目标实际上是从数据访问代码中删除任何事务划分代码:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void doSomeWork() {
// Do some work
factory.getCurrentSession().load(...);
factory.getCurrentSession().persist(...);
}
我的问题:
-
在“actory.getCurrentSession() . load(...);”行中,“factory”是什么类型,我该如何创建它?是Hibernate.SessionFactory吗?还是Jboss或HTTP会话?
-
在“@PersistenceContext(name =”sample“)行EntityManager em中;什么是“名字”指的是什么?我在论坛上找到了一个使用“unitName”而不是“name”的例子 . 这行是如何我首先声明我用来调用.persist() . find()等的EntityManager对象? (因此我的代码不需要创建EntityManagerFactory)
-
我应该考虑研究和使用“Java上下文和依赖注入”(CDI)吗?
任何帮助非常感谢 . 请让我知道我应该提供的其他代码或配置文件
Update:
如果我不使用EntityManagerFactory,并使用@PersistenceContext检索EntityManager,那么像我的“会话bean”(基于每个用户会话的类还原保存实体)这样的代码应该是这样做的方式?
@Stateful
@TransactionManagement(value=TransactionManagementType.BEAN)
public class X implements IX {
@PersistenceContext(unitName="MySQL", type=PersistenceContextType.EXTENDED)
private EntityManager em;
@Resource
private UserTransaction tx;
public void doStuff() {
tx.begin();
em.joinTransaction();
em.find(myEntity);
em.perrsist(myEntity);
tx.commit();
}
如果这是正确的轨道,persistence.xml需要什么?从我对doco和网络的所有阅读中,我不确定可能需要哪些内容:
<property name="jboss.entity.manager.factory.jndi.name" value="java:/MyEntityManagerFactory"/>
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.connection.autocommit" value="false"/>
<property name="hibernate.current_session_context_class" value="jta"/>
2 回答
1)答案在你链接的同一份文件中:-)
2)
name
是对persistence.xml
标签persistence-unit
中指定的名称的引用 . 在你的情况下,它是myPersistanceUnitName
.3)是的,如果您了解它并不意味着要更换任何东西,那就意味着促进“ beans 类”(可能是来自AS的资源)的消费 .
另请注意,为了获得托管的EntityManager(带有好处),您不应该从AS获取EntityManagerFactory . 你应该得到EM本身 . 就像你提到的,它是这样的:
它只适用于由AS管理的东西,比如Servlets,其他CDI bean,EJB,......不确定Struts Action类是否会注入它:-)
我也有这个问题 . 我已经缩小到使用
@WebService
时,我们通过@PersistenceContext
注入EntityManager,entitymanager为null .此外,如果我们将数据访问委托给DAO并为DAO类添加
@TransactionAttribute(TransactionAttributeType.MANDATORY)
,它将抛出javax.ejb.EJBTransactionRequiredException
.不知道这是否是一个JBoss错误,它不会向容器管理的事务添加具有
@WebService
注释的无状态会话bean .