Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA transaction/rollback behaviour with objects persisted via cascade

I have two objects Antrag (application) and Anlage (facility). An application can be made for multiple facilities. The application is persisted directly in the DAO. The facilities are persisted via cascade.

@Entity
@Table(name = "EEG_ANTRAG")
public class Antrag implements Serializable {
  private static final long serialVersionUID = -2440344011443487714L;

  @Id
  @Column(name = "ANT_ID", nullable = false)
  @SequenceGenerator(name = "sequenceGeneratorAntrag", sequenceName = "EEG_ANTRAG_SEQ", allocationSize = 1)
  @GeneratedValue(generator = "sequenceGeneratorAntrag")
  @Getter @Setter private Long id;

  @OneToMany(mappedBy = "antrag", cascade = { CascadeType.ALL }, orphanRemoval = true)
  @OrderBy("id ASC")
  @Getter private List<Anlage> anlageList = new ArrayList<Anlage>();

  public Anlage addAnlage(Anlage anlage) 
    anlageList.add(anlage);
    anlage.setApplication(this);
    return anlage;
  }

  /* some more simple attributes; just Strings, boolean, .. */
}

@Entity
@Table(name = "EEG_ANLAGE")
public class Anlage implements Serializable {    
  private static final long serialVersionUID = -3940344011443487741L;

  @Id
  @Column(name = "ANL_ID")
  @SequenceGenerator(name = "sequenceGeneratorAnlage", sequenceName = "EEG_ANLAGE_SEQ", allocationSize = 1)
  @GeneratedValue(generator = "sequenceGeneratorAnlage")    
  @Getter @Setter private Long id;

  @ManyToOne
  @JoinColumn(name = "ANL_ANT_ID")
  @Getter @Setter private Antrag antrag;

 /* some more simple attributes; just Strings, boolean, .. */
}

@Stateless
public class AntragDaoBean implements AntragDaoLocal {
  @PersistenceContext(unitName = "ejb-model")
  private EntityManager em;

  @Override
  public void persistAntrag(Antrag antrag) {
    em.persist(antrag);
  }
}

When an error occurs on inserting the facilities, e.g. some column name is misspelled in the entity, an exception is thrown. The stacktrace indicates, that a rollback was performed. The problem is, that the application is still persisted. Shouldn't the insertion of the application be rolled back as well? We are using EclipseLink 2.4.1. The EclipseLink debug output states, that all inserts are performed in one single transaction. The database is Oracle 11g. Is my ecpectation of the transactional behaviour wrong? How do I get the behaviour I want?

/* shortened exemplary stacktrace for rollback */
EvaluationException:
  javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
EJBTransactionRolledbackException:
  org.jboss.as.ejb3.tx.CMTTxInterceptor.handleEndTransactionException(CMTTxInterceptor.java:115)
RollbackException:
  com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1177)
DatabaseException:
  org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
SQLSyntaxErrorException:
  oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
like image 628
nick Avatar asked Feb 15 '23 20:02

nick


1 Answers

Your expectation is correct: everything should be made in a single transaction, and the insertion of Antrag should be rolled back as well.

I think your persistence-unit is simply not JTA: test in the persistence.xml file that you have something like:

<persistence-unit name="ejb-model" transaction-type="JTA">
<jta-data-source>java:/someNameDB</jta-data-source>
like image 169
V G Avatar answered Feb 17 '23 11:02

V G