我有一个带有两个字符串字段的实体:ID和NAME,NAME有nullable = false。
使用jboss和hibernate我试图插入三条记录,其中一条是错误的,因为字段名称= null。我将事务级别设置为REQUIRES_NEW,因此我希望数据库中有两条记录,而回滚中只有一条记录,但所有记录都会被回滚。
我的错误在哪里?
持久性文件:
<persistence 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_2_0.xsd"
version="2.0">
<persistence-unit name="persistenceUnit" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/myDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
<property name="hibernate.connection.charSet" value="UTF-8"/>
</properties>
</persistence-unit>
</persistence>
实体档案:
@Entity
@Table(name = "myentity")
public class MyEntity implements Serializable {
private String id;
private String name;
@Id
@Column(name = "id")
public String getId() {
return id;
}
public MyEntity() {
}
public MyEntity(String id, String name) {
this.id = id;
this.name = name;
}
public void setId(String id) {
this.id = id;
}
@Column(name = "name", nullable = false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
EJB文件:
@Stateless
public class MyEJB {
protected EntityManager em;
@PersistenceContext(unitName = "persistenceUnit")
public void setEm(EntityManager em) {
this.em = em;
}
@Transactional(Transactional.TxType.REQUIRES_NEW)
private void insert(String id, String name) {
em.merge(new MyEntity(id, name));
}
public void insertTwoRecords() {
insert("id1", "name1");
insert("id2", null);// error field in entity is nullable = false
insert("id3", "name3");
}
}
答案 0 :(得分:0)
交易是基于代理的。将组件MyEJB
注入组件Caller
时,实际注入的是委托给MyEJB的代理。在调用MyEJB之前,此代理检查事务注释并在必要时启动事务:
Caller ---> proxy ----> MyEJB
在这种情况下,MyEJB直接调用另一个私有方法。不仅私有方法不是组件公共接口的一部分,而且方法调用不是从一个组件到另一个组件,因此代理无法拦截调用并启动新事务。