Java JPA Hibernate保存不插入引用的实体

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java JPA Hibernate保存不插入引用的实体相关的知识,希望对你有一定的参考价值。

我有以下两个班级:

@Entity
@Table(name = "TableA")
public class EntityA
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Id")
    private final Integer id = null;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "BId")
    private EntityB b;

    public EntityA(EntityB b)
    {
        this.b = b;
    }
}

@Entity
@Table(name = "TableB")
public class EntityB
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Id")
    private final Integer id = null;

    @OneToOne(mappedBy = "b")
    private final EntityA a = null;
}

当我做

session.save(new EntityA(new EntityB());

数据库仅在Table中插入记录,并将引用Table的列保留为NULL

如果我先插入b,那么a,它可以工作,但它也应该只用一个调用。

其他问题/答案提到注释不正确,但我发现我和提供的解决方案之间没有区别。

我也尝试在@OneToOne注释上添加CascadeType.PERSIST,但这也没有用。

答案

在jpa中,默认级联设置为NONE ...因此默认情况下不会插入(持久化)关系中的实体(在您的情况下为B)...您需要使用@OneToOne注释关系(fetch = FetchType.LAZY,cascade = CascadeType.PERSIST)

另一答案

首先,您必须从实体中删除final关键字。试试这个:

@Entity
@Table(name = "TableA")
class EntityA {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Id")
    private Integer id;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinColumn(name = "BId")
    private EntityB b;


    public Integer getId() {
        return id;
    }


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


    public EntityB getB() {
        return b;
    }


    public void setB(EntityB b) {
        this.b = b;
    }


    public EntityA(EntityB b) {
        this.b = b;
        b.setA(this);
    }
}

@Entity
@Table(name = "TableB")
class EntityB {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "Id")
    private Integer id;

    @OneToOne(mappedBy = "b")
    private EntityA a;


    public Integer getId() {
        return id;
    }

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

    public EntityA getA() {
        return a;
    }

    public void setA(EntityA a) {
        this.a = a;
    }
}

我正在使用spring boot,hibernate和H2数据库

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ApplicationContext app =  SpringApplication.run(DemoApplication.class, args);
        ServiceCascade bean = app.getBean(ServiceCascade.class);
        bean.save();
    }
}

@Service
class ServiceCascade {
    @PersistenceContext
    private EntityManager entityManager;

    @Transactional
    public void save() {
        EntityA entityA = new EntityA(new EntityB());
        entityManager.persist(entityA);
    }
}

以下日志显示正确插入了两个实体

org.hibernate.SQL : insert into tableb (id) values (null)
org.hibernate.SQL : insert into tablea (id, bid) values (null, ?)
o.h.type.descriptor.sql.BasicBinder  : binding parameter [1] as [INTEGER] - [1]

以上是关于Java JPA Hibernate保存不插入引用的实体的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JPA/Hibernate 在孩子的 id 中引用父母的 id?

JPA/Hibernate 在 Spring Boot 应用程序中插入不存在的表

使用 JPA Hibernate 自动保存子对象

如何在JPA / JAVA / Hibernate的两列中插入自动生成的ID

Spring数据JPA存储库saveAll不生成批量插入查询

JPA/Hibernate 类型安全删除查询