2015-04-18 149 views
0

我有一個具有兩個字符串字段的實體:ID和NAME,NAME具有nullable = false。Jboss和交易

隨着jboss和休眠我試圖插入三條記錄,其中之一是錯誤的,因爲字段名稱= 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

交易是基於代理的。當組件MyEJB被注入到組件Caller中時,實際注入的是一個委託給MyEJB的代理。調用MyEJB之前,該代理會檢查事務的註釋,並啓動必要時交易:

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

在這種情況下,MyEJB直接調用另一個,本身私有方法。不僅私有方法不是組件的公共接口的一部分,而且方法調用也不是從一個組件到另一個組件,所以代理無法攔截該調用並開始新的事務。

+0

謝謝JB,你能寫一個例子嗎? – gekomad

+0

一個什麼樣的例子?只需將insert()方法放入另一個無狀態bean中,並注入MyEJB,它將按預期工作。 –