0

This question is similar to this one but the person asking never confirmed if it worked. entityManager.persist(user) -> javax.persistence.EntityExistsException: User@b3089 is already persistent

Scenario ProductCategory has a OneToMany relationship with Account which inversely has a ManyToOne relationship wuth ProductCategory. When ProductCategory is inserted, Accounts are not available. So ProductCategory is inserted without accounts. Later when accounts are available, I would like to insert accounts in the accounts table and also update ProductCategory with Accounts. The issue is with updating accounts in ProducCategory. When I use mgr.persist for productCategory, I get a error Entity already is Persistent!. When I do not use persist (as per suggestion the link, provider(datanucleus) will take care of writing it to the database at commit time), it does not update. The entities and methods are as follows:

@Entity

public class ProductCategory {

    @Id
    @Column(name = "CAT_ID", allowsNull="false")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key catId;

    @Column(name = "CAT_SHORT_NAME", length=30)
    private String catShortName;

    //other fields

    @OneToMany(mappedBy="productCategory",targetEntity=Account.class, 
            fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    private ArrayList<Account> accounts;  

        //getters & setters

@Entity

public class Account {

    @Id
    @Column(name = "ACCT_NBR_KEY", allowsNull="false")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key acctNbrKey;

    @Column(name = "CAT_ID")
    private Key acctCatId;

    //other fields

    @ManyToOne(optional=false, fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    @JoinColumn(name="CAT_ID",  insertable=false, updatable=false)
    private ProductCategory productCategory;

//getters & setters

AccountEndpoint.java


public void insertAccountBulk() {
        log.info("AccountEndpoint.insertAccountBulk....");

        Account account = new Account();

        ProductCategory pc = (new ProductCategoryEndpoint()).getProductCategoryByShortName("Savings");
        account.setProductCategory(pc);
        account.setAcctCatId(pc.getCatId());

        //setting other fields

        //updationg accounts in product category
            getEntityManager().detach(pc);
        if(pc.getAccounts() == null){
            ArrayList<Account> accts = new ArrayList<Account>();
            accts.add(account);
            pc.setAccounts(accts);
        }
        else{
            pc.getAccounts().add(account);
        }
        getEntityManager().merge(pc);    

        **//new ProductCategoryEndpoint().updateProductCategory(pc);** 

ProductCategoryEndpoint.java

@ApiMethod(name = "updateProductCategory")
public ProductCategory updateProductCategory(ProductCategory productcategory) {
    EntityManager mgr = getEntityManager();
    try {
        if (!containsProductCategory(productcategory)) {
            throw new EntityNotFoundException("Object does not exist");
        }
        mgr.persist(productcategory);
    } finally {
        mgr.close();
    }
    return productcategory;
}

    **If I uncomment new `ProductCategoryEndpoint().updateProductCategory(pc)` I get the error Entity already persistent.

If I keep it commented, the account is not updated in ProductCategory**

Community
  • 1
  • 1
DavidC
  • 185
  • 2
  • 10

2 Answers2

0

Try changing the @JoinColumn annotation to allow inserts and updates of the ProductCategory. I think it is preventing the Categories from being associated with the Account.

@ManyToOne(optional=false, fetch=FetchType.EAGER, cascade=CascadeType.ALL)
@JoinColumn(name="CAT_ID")
private ProductCategory productCategory;
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • Removed insertable=false, updateable=false but still getting Entity "ProductCategory@a6f04d" is already persistent! – DavidC Jun 21 '14 at 19:27
  • Thanks to Neil's suggestion, before updating the prouctCategory, I had to detach it by using getEntityManager().detach(pc); Then after adding the account to pc I had to use merge - getEntityManager().merge(pc); This updates the Product Category with Account. I have updated the code above. Up voting Neil's comment. – DavidC Jun 22 '14 at 20:30
  • I also had one more question. If any of you can pls look into it and reply. http://stackoverflow.com/questions/24189665/gae-one-to-one-relationship-delete-giving-error – DavidC Jun 22 '14 at 20:33
0

Judging by your other question you're using GAE/Datastore NOT RDBMS, and so are not using Hibernate - please update your question and remove that tag.

About the problem, if the entity is already persistent then you are trying to persist an object with a particular Key when an object with that Key already exists (i.e you passed a TRANSIENT object to persist. You should pass a DETACHED object to that method. The log would tell you what state objects are in

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29