【问题标题】:DataNucleus getObjectById returns null for forighn key objetcsDataNucleus getObjectById 为外键对象返回 null
【发布时间】:2025-12-20 15:20:24
【问题描述】:

我有以下持久类

@PersistenceCapable
public class PasswordRecovery {

@PrimaryKey @Expose
@Persistent(valueStrategy = IdGeneratorStrategy.UNSPECIFIED)
private String id;

@Persistent @Expose
private long time;

@Persistent @Expose
private User user;


public PasswordRecovery(String id, long time, User user) {
    this.id = id;
    this.time = time;
    this.user = user;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public long getTime() {
    return time;
}

public void setTime(long time) {
    this.time = time;
}

public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}

现在我正在使用以下代码来获取上面的对象填充 DB 值,

PersistenceManager pm = pmf.getPersistenceManager();
    //PasswordRecovery retObj = null;// = new PasswordRecovery();
    try {           
        PasswordRecovery record = pm.getObjectById(PasswordRecovery.class, id);

        if (null == record) {
            throw new IllegalArgumentException("You are not authorized for this");
        }
        else {                               
            return record;
        }

    } finally {
        pm.close();
    }

现在当我调用record.getUser() 时,它返回null。有没有需要做的配置。以下是我如何创建 PersistenceManagerFactory 的代码。

Properties properties = new Properties();
                   properties.setProperty("javax.jdo.PersistenceManagerFactoryClass","org.datanucleus.api.jdo.JDOPersistenceManagerFactory");
            properties.setProperty("javax.jdo.option.ConnectionURL","jdbc:mysql://localhost/db");                        properties.setProperty("javax.jdo.option.ConnectionDriverName","com.mysql.jdbc.Driver");  
properties.setProperty("javax.jdo.option.ConnectionUserName","username");
properties.setProperty("javax.jdo.option.ConnectionPassword","password");
properties.setProperty("datanucleus.autoCreateSchema","true");
properties.setProperty("datanucleus.autoCreateSchema","true");
properties.setProperty("datanucleus.autoCreateSchema","true");
properties.setProperty("datanucleus.autoCreateTables","true");
pmf = JDOHelper.getPersistenceManagerFactory(properties);

我对 DataNucleus JDO 还是很陌生?配置中是否缺少任何东西?

【问题讨论】:

  • 这是为了达到什么目的? @Persistent(valueStrategy = IdGeneratorStrategy.UNSPECIFIED)。你有一个未指定的价值策略?!那是什么意思?为什么每个字段都有@Persistent?
  • 我对 data-nucleus 很陌生。我想将随机生成的字符串原样存储到主键中,因此我指定了@Persistent(valueStrategy = IdGeneratorStrategy.UNSPECIFIED)。除此之外,我的所有值都存储到数据库中,所以我在每个字段上都指定了@Persistent。
  • 除非你告诉它这些“随机生成的字符串”是如何生成的,否则它不会生成任何东西(并坚持你在那里输入的值)。您不需要在每个字段上都使用@Persistent,默认情况下它们会被持久化!
  • 随机生成的字符串是使用“UUID.randomUUID().toString()”java 代码生成的。我将从其他字段中删除@Persistent。
  • 仍然 getUser 返回 null。如果有人遇到同样的错误,请提出建议。

标签: java mysql servlets jdo datanucleus


【解决方案1】:

因此假设对象由 getObjectById 返回,那么您应该查看 JDO 对象生命周期状态,并了解一旦对象在事务之外它是 HOLLOW,因此所有关系字段都会丢失它们的值,除非您设置 datanucleus.retainValues

【讨论】: