Hubi
Hubi

Reputation: 560

How to fix: javax.persistence.TransactionRequiredException?

I want to delete related data from three tables with one query. I'm getting the error message: javax.persistence.TransactionRequiredException: Executing an update/delete query

We use java 8, Hibernate ORM 5.4.0 and MySQL. Of course, I have already looked here but could not find a suitable answer to my problem. @Transactional could not help me as a class or method name notation.

This is how my method to delete looks like:

public void delteAllAccountsAndValues(Long accountIdToDelete) {
        try {
            startOperation(false);
            getSession().createQuery("DELETE FROM AccountEntity WHERE accountId = :accountIdToDelete")
                    .setParameter("accountIdToDelete", accountIdToDelete)
                    .executeUpdate();
            List accountLineIdsToDelete =
                    getSession()
                            .createQuery("SELECT ale.accountlineId FROM AccountlineEntity ale WHERE ale.accountId IN :accountIdToDelete")
                            .setParameter("accountIdToDelete", accountIdToDelete)
                            .list();
            getSession().createQuery("DELETE FROM AccountlineEntity WHERE accountlineId = :accountLineIdsToDelete")
                    .setParameter("accountLineIdsToDelete", accountLineIdsToDelete)
                    .executeUpdate();
            List accountLineValuesIdsToDelete =
                    getSession().createQuery("SELECT alve.accountlinevaluesId FROM AccountlinevaluesEntity alve WHERE" +
                            " alve.accountlineId IN :accountLineIdsToDelete")
                            .setParameter("accountLineIdsToDelete", accountLineIdsToDelete)
                            .list();
            getSession().createQuery("DELETE FROM AccountlinevaluesEntity WHERE accountlinevaluesId = : accountLineValuesIdsToDelete")
                    .setParameter("accountLineValuesIdsToDelete", accountLineValuesIdsToDelete)
                    .executeUpdate();
        } catch (HibernateException e) {
            handleException(e);
        } finally {
            getSession().close();
        }
    }


Part of my BaseManager class:



  void startOperation(boolean openTransaction) throws HibernateException {
    this.session = HibernateUtil.getSessionFactory().openSession();
    if (openTransaction) {
      this.tx = session.beginTransaction();
    }
  }

  void handleException(HibernateException e) {
    System.out.println(e.getMessage());
    if (e.getCause() != null) {
      System.out.println(e.getCause().getMessage());
    }
    if (this.tx != null) {
      this.tx.rollback();
    }
  }

  protected Session getSession() {
    return session;
  }

  protected void setSession(Session session) {
    this.session = session;
  }

  protected Transaction getTx() {
    return tx;
  }

  protected void setTx(Transaction tx) {
    this.tx = tx;
  }

  public UserEntity getCurrentUser() {
    return currentUser;
  }

  public void setCurrentUser(UserEntity currentUser) {
    this.currentUser = currentUser;
  }

The entities are all the same from the construction, so example one of my entities:

@Entity
@Table(name = "account")
public class AccountEntity {
    @Expose() private Long accountId;
    private String sourcedata;
    private Timestamp dateCreated;
    private Integer parentId;
    @Expose() private MandantEntity mandantEntity;
    @Expose() private UserEntity userEntity;


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "account_id", nullable = false)
    public Long getAccountId() {
        return accountId;
    }

    public void setAccountId(Long accountNewId) {
        this.accountId = accountNewId;
    }

    @Basic
    @Column(name = "sourcedata", nullable = false)
    public String getSourcedata() {
        return sourcedata;
    }

    public void setSourcedata(String sourcedata) {
        this.sourcedata = sourcedata;
    }

    @Basic
    @CreationTimestamp
    @Column(name = "date_created")
    public Timestamp getDateCreated() {
        return dateCreated;
    }

    public void setDateCreated(Timestamp dateCreated) {
        this.dateCreated = dateCreated;
    }

    @Basic
    @Column(name = "parent_id")
    public Integer getParentId() {
        return parentId;
    }

    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }

   ...



I can't get any further at this point right now. Does anyone have any idea where exactly the problem might be?

Upvotes: 1

Views: 529

Answers (1)

Maciej Kowalski
Maciej Kowalski

Reputation: 26522

1) You do not open a transaction by passing false here:

startOperation(false);

2) In the finally block or just before the end of try block you have to commit it:

    } finally {
        getTx().commit();
        getSession().close();
    }

Upvotes: 1

Related Questions