Search code examples
jpaeclipselinkweblogic-10.x

EclipseLink with container managed transactions - persist() does not commit


I'm using EclipseLink 2.1.3 with WebLogic 10.3.5 container managed transactions to interface with an Oracle 11g DB.

I can select data with no problems, but am unable to persist entities.

There are no exceptions raised nor errors in the log, but there is no data committed to the ANNOUNCEMENT_DELIVERY_LOG table.

The AnnouncementDeliveryLog Entity has a @ManyToOne relationship to the Announcement Entity. I first retrieve an existing Announcement Entity, then create an AnnouncementDeliveryLog Entity based on a query result, associate the two Entities, and persist.

Any advice on how what I'm doing wrong or how to get more logging information out of EclipseLink on WebLogic would be appreciated.

AnnouncementDeliveryLog Entity:

@Entity
@Table(name = "ANNOUNCEMENT_DELIVERY_LOG")
public class AnnouncementDeliveryLog implements Serializable {

    @Id
    @Column(nullable = false)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ANNOUNCEMENT_DELIVERY_LOG_SEQ")
    @SequenceGenerator(name="ANNOUNCEMENT_DELIVERY_LOG_SEQ", sequenceName="ANNOUNCEMENT_DELIVERY_LOG_SEQ")
    private BigDecimal id;
    @Column(name = "RECIPIENT_ADDRESS ", nullable = false, unique = true, length = 240)
    private String recipientAddress;
    @ManyToOne
    @JoinColumn(name = "ANNOUNCEMENT_ID ")
    private Announcements announcement;
}

Announcements Entity:

@Entity
@Table(name = "ANNOUNCEMENTS")
public class Announcements implements Serializable {
    @Id
    @Column(nullable = false)
    private BigDecimal id;
    @OneToMany(mappedBy = "announcement")
    private List<AnnouncementDeliveryLog> announcementDeliveryLogList;
}

Session Facade SLSB performing transaction:

@Stateless(name = "DeliveryEngineSessionFacade",
           mappedName = "Announcements-JMSDeliveryEngine-DeliveryEngineSessionFacade")
public class DeliveryEngineSessionFacadeBean implements DeliveryEngineSessionFacadeLocal {
    @Resource
    SessionContext sessionContext;
    @PersistenceContext(unitName = "JMSDeliveryEnginePersistenceUnit")
    private EntityManager em;

    private List<AnnouncementDeliveryLog> createNormalizedEmailADLsForAnnouncement(int announcementId) {
        List<Object[]> rawResultList;
        ArrayList<AnnouncementDeliveryLog> typedResultList = new ArrayList<AnnouncementDeliveryLog>();

        Query query =
            em.createNamedQuery(AnnouncementDeliveryLog.FIND_NORMALIZED_RECIPIENTS_FOR_ANNOUNCEMENT);
        query.setParameter(1, announcementId);
        rawResultList = query.getResultList();

        for (Object[] resultElement : rawResultList) {
            AnnouncementDeliveryLog adl = new AnnouncementDeliveryLog(getAnnouncementById(announcementId), (String)resultElement[1], (String)resultElement[2], "TO_SEND");
            adl = persistAnnouncementDeliveryLog(adl);
            typedResultList.add(adl);
        }

        return typedResultList;
    }

public AnnouncementDeliveryLog persistAnnouncementDeliveryLog(AnnouncementDeliveryLog announcementDeliveryLog) {
    em.persist(announcementDeliveryLog);
    return announcementDeliveryLog;
}

public Announcements getAnnouncementById(int announcementId) {
    Query query = em.createNamedQuery(Announcements.FIND_BY_ID);
    query.setParameter("id", announcementId);
    return (Announcements)query.getSingleResult();
}

}

SLSB invoking Session Facade:

@Stateless(name = "RecipientsPopulationTimer",
           mappedName = "Announcements-AnnouncementDeliveryEngine-RecipientsPopulationTimer")
@Local({RecipientsPopulationTimerLocal.class})
public class RecipientsPopulationTimerBean implements RecipientsPopulationTimerLocal {
    @EJB
    DeliveryEngineSessionFacadeLocal sessionFacade;
}

persistence.xml

<?xml version="1.0" encoding="UTF-8" ?>
<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="JMSDeliveryEnginePersistenceUnit">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/announcementsDS</jta-data-source>
        <class>announcements.deliveryengine.jpa.entities.AnnEmailRecipientsFlattened</class>
        <class>announcements.deliveryengine.jpa.entities.AnnImRecipientsFlattened</class>
        <class>announcements.deliveryengine.jpa.entities.AnnouncementDeliveryLog</class>
        <class>announcements.deliveryengine.jpa.entities.Announcements</class>
        <class>announcements.deliveryengine.jpa.entities.AnnouncementRecipients</class>
        <class>announcements.deliveryengine.jpa.entities.AnnouncementRecipientsFlattenedId</class>
        <properties>
            <property name="eclipselink.target-server" value="WebLogic 10"/>
            <property name="eclipselink.logging.level" value="FINE"/>
            <property name="eclipselink.logging.exceptions" value="true"/>
            <property name="eclipselink.logging.timestamp" value="true"/>
            <property name="eclipselink.logging.thread" value="true"/>
            <property name="eclipselink.logging.session" value="true"/>
            <property name="eclipselink.logging.level.sql" value="FINE"/>
            <property name="eclipselink.logging.parameters" value="true"/>
            <property name="eclipselink.target-database" value="Oracle11"/>
        </properties>
    </persistence-unit>
</persistence>

Solution

  • RecipientsPopulationTimerBean was being invoked by a component that had a timeout on it.

    This meant that the EJB transaction was rolledback because the DB transaction took too long.

    Setting @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) on the appropriate DB transaction methods prevented the EJB timeout and associated DB rollback.