2015-04-18 3 views
0

У меня есть сущность с двумя строковыми полями: ID и NAME, NAME имеет значение nullable = false.Jboss и транзакция

С 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

Сделки прокси основе. Когда компонент MyEJB вводится в компонент Caller, то, что на самом деле вводится, является прокси-сервером, который делегирует MyEJB. Перед вызова MyEJB, этот прокси проверяет транзакционные аннотации и начинает транзакцию, если необходимо:

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

В этом случае MyEJB непосредственно вызывает другой, частный метод сам по себе. Не только частные методы не являются частью открытого интерфейса компонента, но вызов метода не от одного компонента к другому, поэтому прокси-сервер не может перехватить вызов и начать новую транзакцию.

+0

спасибо JB, вы можете написать пример? – gekomad

+0

Пример чего? Просто поместите метод insert() в другую фазу без состояния, введенную в MyEJB, и она будет работать, как ожидалось. –

Смежные вопросы