Jboss和交易

时间:2015-04-18 10:40:54

标签: hibernate jboss transactions jta

我有一个带有两个字符串字段的实体: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");
        }
    }

1 个答案:

答案 0 :(得分:0)

交易是基于代理的。将组件MyEJB注入组件Caller时,实际注入的是委托给MyEJB的代理。在调用MyEJB之前,此代理检查事务注释并在必要时启动事务:

Caller ---> proxy ----> MyEJB

在这种情况下,MyEJB直接调用另一个私有方法。不仅私有方法不是组件公共接口的一部分,而且方法调用不是从一个组件到另一个组件,因此代理无法拦截调用并启动新事务。