Объект не сохраняется с использованием JPA / JTA / JBOSS / CDI

1

Пожалуйста, помогите мне понять, почему объект не сохраняется с помощью следующего кода. Он бросает javax.persistence.TransactionRequiredException: JBAS011469: для выполнения этой операции требуется транзакция (либо использовать транзакцию, либо расширенный контекст сохранения)

public class OrganizationRepositoryImpl implements OrganizationRepository {

    @PersistenceContext(unitName="usermanagement",type=PersistenceContextType.TRANSACTION)
    private EntityManager em;

    public void save(Organization organization) {
        try {
            em.persist(organization);
        }catch(Exception e) {
            e.printStackTrace();

        }
    }    
}

Но если я аннотирую класс с аннотацией @Stateless (теперь ejb), объект начнет сохраняться

@Stateless    
public class OrganizationRepositoryImpl implements OrganizationRepository {

            @PersistenceContext(unitName="usermanagement",type=PersistenceContextType.TRANSACTION)
            private EntityManager em;

            public void save(Organization organization) {
                try {
                    em.persist(organization);
                }catch(Exception e) {
                    e.printStackTrace();

                }
            }    
        }

persistence.xml

    <?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
        version="2.1">
    <persistence-unit name="usermanagement" transaction-type="JTA">
        <jta-data-source>java:jboss/datasources/MysqlXADS</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
             <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
             <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
             <property name="hibernate.show_sql" value="true"/>
             <property name="hibernate.format_sql" value="true"/>  
             <property name="use_sql_comments" value="true"/>
             <property name="jboss.entity.manager.factory.jndi.name" value="java:jboss/myEntityManagerFactory" /> 
        </properties>
    </persistence-unit>
</persistence>

Класс обслуживания для вызова репозитория для сохранения объекта в базе данных

    public class OrganizationServiceImpl implements OrganizationService {

    @Inject
    private OrganizationRepository orgRepo;

    public Response createOrganization(InputStream is) {
        Organization org = null;
        org = readStream(is);
        orgRepo.save(org);
        return Response.created(URI.create("/organizations/" + org.getId()))
                .build();
    }

    private Organization readStream(InputStream is) {
        JAXBContext context;
        Organization org = null;
        try {
            context = JAXBContext.newInstance(Organization.class);
            Unmarshaller um = context.createUnmarshaller();
            org = (Organization) um.unmarshal(is);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return org;
    }
}  
Теги:
jpa
java-ee
jboss7.x
jta

2 ответа

7

Когда вы объявляете bean-компонент как @Stateless методы в этом компоненте по умолчанию являются транзакционными. Транзакционные методы фиксируют состояние сохранения при полном выполнении.

Если у вас нет класса, аннотированного с помощью методов @Stateless, по умолчанию транзакция не выполняется, и, следовательно, вы получаете указанное исключение.

  • 0
    Это правда, так как я могу сделать это методами bean-компонента Transactional, не делая bean-компонент EJB (@Stateless). Я пытался аннотировать метод с помощью @Transactional (vale = TxType = Required), но все равно получал то же исключение.
  • 1
    Другой день, другая аннотация, которая имеет другое поведение, которое четко не задокументировано.
3

Я не слишком знаком с EJB, но я считаю, что проблема заключается в том, что без аннотации @Stateless этот компонент не является EJB, поэтому транзакции автоматически не управляются. Если вам нужна сдержанность, используйте @Stateful аннотацию, чтобы создать EJB с состоянием. Если вы не хотите использовать EJB, вам необходимо вручную управлять своими транзакциями, используя EntityManager.

tx = em.getTransaction();
tx.begin();

// do some work
...

tx.commit();

Ещё вопросы

Сообщество Overcoder
Наверх
Меню