【问题标题】:JPA - Entity is already persistent - using GAEJPA - 实体已经持久 - 使用 GAE
【发布时间】:2014-08-12 04:01:24
【问题描述】:

这个问题与这个问题类似,但询问的人从未确认它是否有效。 entityManager.persist(user) -> javax.persistence.EntityExistsException: User@b3089 is already persistent

场景 ProductCategoryAccount 具有 OneToMany 关系,而后者与 ProductCategory 具有 ManyToOne 关系。插入ProductCategory 时,帐户不可用。所以ProductCategory 是在没有帐户的情况下插入的。稍后当帐户可用时,我想在帐户表中插入帐户,并使用 Accounts 更新 ProductCategory。问题在于更新 ProductCategory 中的帐户。当我对 productCategory 使用 mgr.persist 时,我收到一个错误 Entity already is Persistent!。当我不使用持久化(根据链接的建议,provider(datanucleus) 将负责在提交时将其写入数据库),它不会更新。实体和方法如下:

@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.

如果我保持评论,则帐户不会在ProductCategory**中更新

【问题讨论】:

  • 您是如何组织代码的?第二段代码是ProductCategoryEndpoint 上的updateProductCategory 方法吗?最好只是发布类定义,当前的语法非常不正统。
  • 凯文,我已经更新了 ProductCategoryEndpoint.updateProductCategory()
  • 太好了,我正在尝试重新创建您的示例来摆弄,这需要一分钟。
  • BTW Key 类是什么?
  • Google App 引擎为其数据存储区提供了一个 Key 类 (com.google.appengine.api.datastore.Key)。

标签: java android google-app-engine jpa


【解决方案1】:

根据您的其他问题判断,您使用的是 GAE/Datastore NOT RDBMS,因此没有使用 Hibernate - 请更新您的问题并删除该标签。

关于这个问题,如果实体已经是持久的,那么当具有特定键的对象已经存在时,您尝试使用特定键来持久化一个对象(即您传递了一个 TRANSIENT 对象来持久化。您应该将一个 DETACHED 对象传递给那个方法。日志会告诉你什么状态对象在

【讨论】:

    【解决方案2】:

    尝试更改@JoinColumn 注释以允许插入和更新ProductCategory。我认为这会阻止CategoriesAccount 关联。

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

    【讨论】:

    • 删除了 insertable=false, updateable=false 但仍然得到实体“ProductCategory@a6f04d”已经是持久的!
    • 感谢 Neil 的建议,在更新 prouctCategory 之前,我不得不使用 getEntityManager().detach(pc); 将其分离。然后将帐户添加到 pc 后,我不得不使用 merge - getEntityManager().merge(pc);这将使用帐户更新产品类别。我已经更新了上面的代码。投票支持 Neil 的评论。
    • 我还有一个问题。如果你们中的任何人都可以请查看并回复。 stackoverflow.com/questions/24189665/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 2015-11-02
    • 1970-01-01
    相关资源
    最近更新 更多