简体   繁体   中英

WebSphere 8.5 - Rest - No active Transaction

I am struggling with WAS8.5 to use a simple Rest Service + an EJB to insert an entity into my DB2 database. Selecting works fine, because no transaction is needed. The Entity is correctly annotated. (successful select proves at least that)

I always get the following exception:

javax.persistence.TransactionRequiredException: No active transaction for PuId=project.ear#included.war#persistence-unit-name
[29.08.13 15:14:59:714 CEST] 00000071 SystemErr     R   at com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:221)
[29.08.13 15:14:59:714 CEST] 00000071 SystemErr     R   at com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:179)
[29.08.13 15:14:59:714 CEST] 00000071 SystemErr     R   at com.ibm.ws.jpa.management.JPAEntityManager.persist(JPAEntityManager.java:143)
[29.08.13 15:14:59:714 CEST] 00000071 SystemErr     R   at com.TestFacade.testEMInsert(TestFacade.java:72)

My persistence.xml (placed in META-INF):

<?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 http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit
              name="persistence-unit-name"
              transaction-type="JTA">

        <!-- <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> -->
        <!-- <provider>com.ibm.websphere.persistence.PersistenceProviderImpl</provider> -->
        <jta-data-source>jdbc/test-services-ds</jta-data-source>

        <class>com.EntityTest</class>

        <properties>
            <!--<property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>-->
            <property name="openjpa.Log" value="SQL=TRACE"/>
            <!-- PrintParameters will show query parameters, remove when development has been finished -->
            <!-- <property name="openjpa.ConnectionFactoryProperties"  value="PrettyPrint=true, PrettyPrintLineLength=72, PrintParameters=true"/> -->
            <property name="openjpa.jdbc.Schema" value="LKWSQL"/>
            <property name="openjpa.TransactionMode" value="managed"/>
            <property name="openjpa.ConnectionFactoryMode" value="managed"/>
            <property name="openjpa.jdbc.DBDictionary" value="db2"/>
        </properties>
    </persistence-unit>
</persistence>

The persistence.xml will be read so i think the packaging of the ear seems to be ok. I know in JavaEE6 a war would be sufficent, but it was already an existing project setup. The Team before us switched to user managed transactions, but i hope somebody can help me to point out the mistake.

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED) // default, but was worth a try
@Path("servicepath")
public class TestFacade implements ITestFacade {

    @Inject
    private SearchService searchService;
    @PersistenceContext(unitName="persistence-unit-name")
    private EntityManager em;

The search service caused the first troubles. With @EJB it always was null. @Inject from CDI worked. Maybe that's a clue?

@GET
@Path("testInsert/")
@Produces({ MediaType.TEXT_PLAIN })
public String testEMInsert() {
try{
    System.out.println("testing Insert: " + em.isOpen()); // open is true
    EntityTest e = new EntityTest("name");
            em.persist(e);

} catch (Exception e){
    e.printStackTrace();
    return e.getMessage();
}

return "OK";
 }

I hope anyone has an idea what i could check. Had to change the facade+service names. :-/ greetings m

@mkuff - I develop an ear project that targets WAS v8.0.0.7.

All I need to get an EJB properly configured is this:

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.persistence.EntityManager;
@Stateless
public class StateInfo {
    @Inject
    @SomeDatabase
    private EntityManager em;

To load the WAS 8.xx libraries, my Maven pom uses the dependency:

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>6.0</version>
        <scope>provided</scope>
    </dependency>

As for the @SomeDatabase annotation...that's present because I leverage WAS's CDI (OpenWebBeans). Here's my Qualifier:

import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

/**
 * @author Chris Harris
 *
 */
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({FIELD, TYPE, METHOD})
public @interface SomeDatabase {}

Then, I use a Producer:

import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 * @author Chris Harris
 *
 */
public class JPAResourceProducer {
@SuppressWarnings("unused")
@Produces
@PersistenceContext(unitName = "somePuName")
@SomeDatabase
private EntityManager em;
}

Here's 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 
                             http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="somePuName" transaction-type="JTA">
    <jta-data-source>java:comp/env/someDb</jta-data-source>

Here's the relevant part of web.xml:

<resource-ref id="someDb">
    <res-ref-name>someDb</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

And finally, ibm-web-bnd.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-bnd 
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_1.xsd"
version="1.1">

<virtual-host name="default_host" />

<resource-ref name="someDb" binding-name="jdbc/someDb" />

I have a DataSource defined in WAS that uses the name jdbc/someDb.

The root cause was a bug in websphere combined with the absent classes array returned from the Rest Application config class. When our EJB implemented an Interface it simply did not work anymore. EJB not recognized and no transaction started.

I marked Chriss answer, because it containes more useful information. Thanks a lot for that!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM