【问题标题】:Setting 1-1 Relation to existing object inserts new object instead using JDO?设置 1-1 与现有对象的关系会插入新对象而不是使用 JDO?
【发布时间】:2017-12-30 21:07:27
【问题描述】:

每当我尝试将其设置为对象属性时,都会创建一个新对象。让别人重现这个。这是默认行为吗?

public class ProductClass implements Serializable {
...
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
long id;
@Persistent
private String name = null;
...
}


public class Product implements Serializable {
...
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
long id;
@Persistent
private String name = null;
@Persistent(defaultFetchGroup = "true")
private ProductClass productClass = null;
...
}

这就是我通过实现我的ProductClassNeo4jService 从数据库中检索ProductClass 的方式;

@Override
public ProductClass findById(Long id) {
    if (id == null) {
        return null;
    }
    PersistenceManager pm
            = JDOUtil.PERSISTENCE_MANAGER_FACTORY.getPersistenceManager();
    ProductClass prod = null;

    try {
        prod = (ProductClass) pm.getObjectById(ProductClass.class, id);
    } finally {
        pm.close();
    }
    return prod;
}

...
ProductClass prodClass = productClassNeo4jService.findById(id);

像这样坚持产品;

...
Product prod = new Product();
prod.setName('productName');
prod.setProductClass(prodClass);

PersistenceManager pm = JDOUtil.PERSISTENCE_MANAGER_FACTORY.getPersistenceManager();
Transaction tx = pm.currentTransaction();
try {
tx.begin();
pm.makePersistent(prod);
Object id = pm.getObjectId(prod);
tx.commit();
} finally {
    if (tx.isActive()) {
        tx.rollback();
    }
    pm.close();
}
...

生成新的 ProductClass,而不是将 ProductClass 设置为 Product。我做错了什么?

【问题讨论】:

  • 什么是“非字符串对象”?你有一个1-1的关系! prodClass 是在哪里创建的?在调用makePersistent 时它处于什么对象生命周期状态?所有这些都在 JDO 规范和任何体面的 JDO 文档中定义
  • @DN1 谢谢,我已经添加了如何检索prodClass。 productClass(es) 已经创建。要创建一个新产品,该产品必须属于一个产品类。也就是你说的1-1关系。对吗?
  • 所以它是在事务之外检索的,因此是 TRANSIENT 吗?还是分离的?
  • 是的。它是在该事务之外检索的。您可以看到我不使用事务来读取数据,而是仅在写入数据库时​​使用。我认为,查看模型注释,它是分离的。 @PersistenceCapable(identityType = IdentityType.APPLICATION, cacheable = "false", detachable = "true") public class ProductClass implements Serializable {
  • 因此请查看日志,因为它会告诉您所有这些,以及正在发生的事情......

标签: java neo4j jdo datanucleus


【解决方案1】:

感谢 JDO 2.0 提供了名为 attach/detach 的功能,该功能允许分离对象以在其他地方使用,然后在您想要在对象中保留任何更改的数据时附加它们。我得到的ProductClass 不拆是没用的。感谢@DN1。我修改了我的代码,通过添加一行来分离 ProductClass。

看起来像这样;

@Override
public ProductClass findById(Long id) {
    if (id == null) {
        return null;
    }
    PersistenceManager pm
            = JDOUtil.PERSISTENCE_MANAGER_FACTORY.getPersistenceManager();
   Transaction tx = pm.currentTransaction();

    ProductClass prod = null;

    try {
        tx.begin();

        prod = (ProductClass) pm.getObjectById(ProductClass.class, id);
       // Detach our productClass object for use elsewhere
       prod =  pm.detachCopy(prod);

       tx.commit();
    } finally {
        if (tx.isActive()) {
            tx.rollback();
        }
        pm.close();
    }
    return prod;
}

为方便起见,将javax.jdo.option.DetachAllOnCommit = true 添加到您的 PMF 选项中。

实际的问题是我在 Transaction 之外进行了所有这些操作。 将javax.jdo.option.DetachAllOnCommit 添加到您的persistence.xml 仅适用于Transaction

【讨论】:

  • 但如果您使用的是事务,则不需要detachCopy。如果您在没有事务的情况下执行此操作,您可以设置 datanucleus.detachOnClose 以便在关闭 PM 时分离所有读入对象。
  • @DN1 是的。我已经观察到了。我花了一些时间和您的帮助来找出它没有分离的原因。谢谢。
  • 在我的persistence.xml 中设置datanucleus.DetachAllOnCommit= truedatanucleus.detachOnClose = true 会不会有冲突,因为我更喜欢在没有事务的情况下读取数据?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多