Configuring EJB on JBoss AS 7 using JTA datasource

2019-01-25 20:53发布

问题:

everybody!

I've been trying to find the answer for some time but I didn't manage.

I try to configure my application and make it work under JBoss Application Server 7.1.1, using Enterprise Java Beans. My application is Web application, it uses servlets and injects other classes as EJBs. The problem is that every statement gets commited, so that means no transaction management is supported.

In my test example I have an entity with a collection of children (mapped with a relationship OneToMany with a property CascadeType.ALL). If a record in a collection has some problems (e.g. non-existing foreign key), it can't be inserted into table and throws exception. However, the parent entity gets inserted, so I assume the inserts are done in different separate transactions. This is strictly undesired behavior and I try to resolve it.

Technical parameters:

DBMS: Oracle EE 11g

AS: JBoss AS 7.1.1

my persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
   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/">
   <persistence-unit name="OracleEntityManager">
      <jta-data-source>java:jboss/CmaDevDS</jta-data-source>
      <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect" />
        <property name="hibernate.hbm2ddl.auto" value="none" />
        <property name="hibernate.jdbc.batch_size" value="20" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />
        <property name="hibernate.use_sql_comments" value="true" />
      </properties>
   </persistence-unit>
</persistence>

my EJB:

@Stateless(name="EntityWriter")
@TransactionManagement(TransactionManagementType.CONTAINER)
public class EntityWriter {

    @Resource
    private SessionContext context;
    /*@Resource
    UserTransaction ut;*/
    @PersistenceContext(unitName = "OracleEntityManager",type=PersistenceContextType.EXTENDED)
    EntityManager em;

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public EntityMarker insertEntity(EntityMarker entity)throws Exception
    {
        try
        {
            entity = em.merge(entity);
            em.flush();
            return entity;
        }
        catch (Exception e)
        {
            context.setRollbackOnly();
            e.printStackTrace();
            return null;
        }
    }
}

Actually I tried both EJB approaches: Container Management Transaction and Bean Management Transaction and neither works as I expect.

When I inject the bean into servlets I do it like this:

    @EJB(name = "EntityWriter")
    private EntityWriter entityWriter;

Now I think the bean is fine, probably something is missing in persistence.xml.

Would be grateful to any ideas. Thanks in advance!

回答1:

Everything works correct after I edited Datasource configuration via JBoss Administration console and set a checkbox "Use JTA". It was unchecked by default.

You're right, Chris. Thanks!