【问题标题】:How to not update a joined entity JPA如何不更新加入的实体 JPA
【发布时间】:2020-05-22 10:06:32
【问题描述】:

我将简要解释一下情况。 我有 2 个实体,一个是所有者并拥有 FK,而另一个是加入的实体。 情况是所有者只能关联一个非所有者,而非所有者可以有多个所有者。 但是,我认为我需要的是单向 OneToOne,因为我希望能够在所有者端执行所有 CRUD 操作,但我不希望由于我的操作而更新或删除任何非所有者我对主人做的。如果这个推理是错误的,请纠正我。所以这就是我所拥有的:

@Entity
public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;

    @Column
    private fk_id;

// various fields with their getter and setters
    @OneToOne
    @JoinColumn(name = "fk_id", referencedColumnName = "id", insertable = false, updatable = false)
    private Child childEntity;
}

@Entity
public class Child{
    @Id
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;
}

我遇到的问题如下: - 尝试插入具有有效 fk_id 的新所有者会导致 必须在调用 save() 错误之前手动分配此类的 id 我尝试解决此问题,但很快意识到这实际上不是问题。我遇到了这个问题,因为当创建一个新的 Owner JPA 实际上试图创建一个链接到这个父级的子级时,它不能这样做,因为我没有 ID 的生成策略(这是我想要的)。

经过多次尝试后,我觉得这是问题所在,我无法添加链接到已存在子级的新父级,因为对于每个尝试添加的父级,JPA 都会尝试添加相应的新子级。

我想我可以用单向 OneToOne 关系解决这个问题,但要么我做错了,要么有其他问题,因为单向 OneToOne 需要我不想要的级联类型。

编辑:我正在尝试插入一个新所有者,该所有者链接到一个非所有者,如下所示:

public Long insertAccount(Owner record) {
        insert(record);
        return record.getId();
    }

public Long insert(T entity) {
        entityManager.persist(entity);
        return entity.getId();
    }

insertable = false, updatable = false 似乎是必要的,因为 fk_id 也是该类的一列。

编辑 2:通过在所有者中具有以下内容:

    @ManyToOne
    @JoinColumn(name = "fk_id", insertable = false, updatable = false)
    private Child childEntity;

我收到以下错误:

对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例

有没有办法在不添加级联选项的情况下修复它?正如我上面提到的,在插入新所有者时,我根本不想更改非所有者方面。

我想到的另一个例子如下: 所有者=对大学有参考的学生 非所有者 = 大学。

学生班有@ManyToOne注解,大学班没有任何注解。我希望它是单向的,我想添加一个新学生,该学生将引用一所大学,但我不想与该学生一起添加另一所大学。

这就是 JPA 正在尝试做的事情

【问题讨论】:

    标签: hibernate jpa hibernate-mapping one-to-one


    【解决方案1】:

    (父 -> 子)关系是多对一

    我不是很明白这个问题,如果子实体已经存在, 您将必须获得 BBDD 的完整对象,以便它不是临时实体 并将其设置为父属性。

    另外,去掉insertable false和updatable false,是隐式的:

    @JoinColumn (name = "fk_id", referencedColumnName = "id", insertable = false, updatable = false)
    

    如果您想将其设置为 true,则必须设置关系类型、删除类型、更新...等

    @ManyToOne (cascade = {CascadeType.MERGE, CascadeType.PERSIST})
    

    你能把你坚持新父亲的那段代码放进去吗?

    编辑 2:

    暂时错误是您尝试插入父实体的原因。它包含一个您想要关联的子实体,该子实体与数据库条目不完全相同。 DDBB 中是否存在子实体?如果响应是肯定的,你有子实体的 id 试试这个:

    public Long insert(T entity) {
        //This line complete te object child
        entity.setChild(em.find(Child.class,entity.getChild().getId()))
        entityManager.persist(entity);
        return entity.getId();
    }
    

    【讨论】:

    • 你对父子关系的看法是绝对正确的。我可能不够清楚,因为我不确定我是否理解正确。实际关系如下:我有实体 x 和实体 y。每个 x 只能有一个 y 与之关联。 y 可以关联许多不同的 x。由于 x 是 FK 的所有者,我认为 OneToOne 关联是最好的。我将编辑我的问题,添加我的坚持方式和这条信息,我为不够清楚而道歉
    猜你喜欢
    • 1970-01-01
    • 2016-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 1970-01-01
    • 2019-02-09
    相关资源
    最近更新 更多