0 votes
1 view
in Java by (10.2k points)

I have a JPA-persisted object model that contains a many-to-one relationship: an Account has many Transactions. A Transaction has one Account.

Here's a snippet of the code:

@Entity

public class Transaction {

    @Id

    @GeneratedValue(strategy = GenerationType.AUTO)

    private Long id;

    @ManyToOne(cascade = {CascadeType.ALL},fetch= FetchType.EAGER)

    private Account fromAccount;

....

@Entity

public class Account {

    @Id

    @GeneratedValue(strategy = GenerationType.AUTO)

    private Long id;

    @OneToMany(cascade = {CascadeType.ALL},fetch= FetchType.EAGER, mappedBy = "fromAccount")

    private Set<Transaction> transactions;

I am able to create an Account object, add transactions to it, and persist the Account object correctly. But, when I create a transaction, using an existing already persisted Account, and persisting the the Transaction, I get an exception:

Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: com.paulsanwald.Account at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141)

So, I am able to persist an Account that contains transactions, but not a Transaction that has an Account. I thought this was because the Account might not be attached, but this code still gives me the same exception:

if (account.getId()!=null) {

    account = entityManager.merge(account);

}

Transaction transaction = new Transaction(account,"other stuff");

 // the below fails with a "detached entity" message. why?

entityManager.persist(transaction);

How can I correctly save a Transaction, associated with an already persisted Account object?

1 Answer

0 votes
by (46.1k points)

This is a standard bidirectional compatibility problem. It is well discussed in this link as well as this link.

As per the provisions in the previous 2 links you require to fix your setters in both parties of the bidirectional connection. An example setter for the One side is in this link.

A standard-setter for the Many sides is in this link.

After you change your setters you want to declare the Entity access type to be "Property". Best practice to declare the "Property" access-type is to move ALL the explanations from the member properties to the corresponding getters. A big word of warning is not to mix "Field" and "Property" access standards within the entity class unless the behavior is undefined by the JSR-317 specs.

Welcome to Intellipaat Community. Get your technical queries answered by top developers !


Categories

...