【问题标题】:Trying to persist an entity with @ManyToOne mapping尝试使用 @ManyToOne 映射持久化实体
【发布时间】:2013-08-08 22:12:44
【问题描述】:

我正在尝试保留一个 User,该 User 具有与 UserStatus

的映射 @ManyToOne

但是当我执行下面的代码时,休眠会抛出 PropertyValueException

user.setStatus(new UserStatus(1));
em.persist(user); // ou session.saveAndUpdate(user);

为了工作,我必须这样做:

user.setStatus(em.getReference(UserStatus.class, 1));
em.persist(user); // ou session.saveAndUpdate(user);

我知道第一种方法是可能的,但我不知道我是否需要配置或调用另一个方法(我已经尝试过从 Session 中保存和更新,仍然一样)

有人知道吗?

错误信息是:

not-null property references a null or transient value

映射

@ManyToOne(optional = false)
@JoinColumn(name = "user_status_id", nullable = false)
public UserStatus getStatus() {
    return status;
}

【问题讨论】:

    标签: java hibernate jpa orm


    【解决方案1】:

    此错误表示“您正在引用一个空(非持久)对象”,您必须选择:删除 nullable 或设置 @Cascade 以便在您这样做时 UserStatus 将永久保留em.persist(user)

    @ManyToOne(optional = false)
    @JoinColumn(name = "user_status_id", nullable = false)
    @Cascade(cascade=CascadeType.ALL)
    public UserStatus getStatus() {
        return status;
    }
    

    编辑:经过各种测试,使用getReference() 是正确的方法,因为new UserStatus(1) 会出错,应该替换为getReference(UserStatus.class,ID) 以返回UserStatus 的代理实例。代理对象未命中数据库,因此避免了 SELECT,并且在 UserStatus 代理上设置的唯一字段是 ID,这是解析 @ManyToOne 关系所必需的!

    一些有用的答案:When to use EntityManager.find() vs EntityManager.getReference()
    What is the difference between EntityManager.find() and EntityManger.getReference()?

    【讨论】:

    • 关系实体已经持久化在数据库中,但是对象没有附加,我不想做一个SELECT只是为了做一个INSERT
    • 所以尝试删除nullable
    • 如果我删除 nullable,hibernate 会尝试在此列中插入 null,这在数据库上不是 NULL
    • 您必须执行 SELECT 因为 Hibernate - 错误 not-null property references a null or transient value 不允许瞬态对象(使用 new 创建)
    • 这不是强制性的。执行 getReference 不会生成任何 SELECT 语句,并且可以正常工作。但我知道有一个解决方案,只需在关联上设置 ID
    猜你喜欢
    • 1970-01-01
    • 2018-05-25
    • 2011-11-01
    • 2016-04-01
    • 2011-07-16
    • 1970-01-01
    • 2013-04-17
    • 2020-04-04
    • 2011-11-15
    相关资源
    最近更新 更多