当前位置: 首页 > 知识库问答 >
问题:

Hibernate PostgreSQL OneToOne关系首先触发子查询

苏君昊
2023-03-14

我正在开发应用程序来学习PostgreSQL上的HiberNate。我目前正在尝试将变量添加到具有OneToOne关系的数据库中。

首先,我用下面的模式在数据库中创建了两个表。在person\u detail表上,它有主键,也是person表的外键。

然后我创建了两个类,Person人格化细节人格化细节是具有OneToOne关系的Person的子类。我使用下面的代码添加人格化细节作为属性的

Person person = new Person(
        "Rick",
        1.7,
        dateFromString("1969-4-2"),
        new Date()
);
PersonDetail personDetail =
        new PersonDetail("myemail@email.com", "Marley");
person.setPersonDetail(personDetail);

session.beginTransaction();

session.save(person);
session.save(personDetail);

session.getTransaction().commit();

System.out.println(person.toString());

但是上面代码的问题是HiberNate首先执行子查询,而不是父查询。

Hibernate:在person_详细信息(地址、电子邮件)中插入值(?,)

由于person仍然为空,我们无法在person\u detail中插入任何行,因为它违反了外键约束。

有办法解决这个问题吗?谢谢

如果有人想检查我是如何注释这两个类的,我会把代码放在下面。

@Entity
@Table(name="person")
@Data
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private int id;

    @Column(name="name")
    private String name;

    @Column(name="height")
    private double height;

    @Column(name="birth_date")
    private Date dateBirth;

    @Column(name="last_seen")
    private Date lastSeen;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "id")
    private PersonDetail personDetail;

    public Person() {}

    public Person(String name, double height, Date dateBirth, Date lastSeen){
        this.name = name;
        this.height = height;
        this.dateBirth = dateBirth;
        this.lastSeen = lastSeen;
    }
}


@Data
@Entity
@Table(name="person_detail")
public class PersonDetail {
    @Id
    @Column(name="id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name="email")
    private String email;

    @Column(name="address")
    private String address;

    public PersonDetail(){}

    public PersonDetail(String email, String address){
        this.email = email;
        this.address = address;
    }
}

共有1个答案

邓韬
2023-03-14

我看到你有主键在表person_details作为外键到表,你可以使用@PrimaryKeyJoin列像这样:

@Entity
@Table(name="person")
@Data
public class Person {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "height")
    private String height;

    @OneToOne(mappedBy = "person", cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private PersonDetail personDetail;

    public Person() {}

    public Person(String name, String height) {
        this.name = name;
        this.height = height;
    }
}

@Data
@Entity
@Table(name="person_detail")
public class PersonDetail {

    @Id
    @Column(name="id")
    private Long id;

    @Column(name="email")
    private String email;

    @OneToOne
    @MapsId
    @JoinColumn(name = "id", referencedColumnName = "id")
    private Person person;


    public PersonDetail(){}

    public PersonDetail(String email){
        this.email = email;
    }
}

如果保存实体,不要忘记将Person设置为PersonDetails:

Person person = new Person("Rick", "1.7");
        
PersonDetail personDetail = new PersonDetail("myemail@email.com");
personDetail.setPerson(person);

person.setPersonDetail(personDetail);
        
repository.save(person);
 类似资料:
  • 初次见面,请多多关照。我是生在博多,成长在Git社区的「猴子老师」。今天我们要来一起学习版本管理系统「Git」哦。 要把文档还原到编辑前的状态,大家都是怎么做的呢? 最简单的方法就是先备份编辑前的文档。使用这个方法时,我们通常都会在备份的文档名或目录名上添加编辑的日期。但是,每次编辑文档都要事先复制,这样非常麻烦,也很容易出错。 再加上,如果像上图那样毫无命名规则的话,就无法区分哪一个文档是最新的

  • 问题内容: 我该如何解决Oracle不允许在触发器中进行子查询的局限性。 这是我尝试创建的示例触发器,但由于无法使用子查询而无法创建。 问题答案: 这个触发器可以做到: 我假设从项目中进行选择将始终找到一行;如果不是,它将引发您可能需要处理的NO_DATA_FOUND异常。

  • 我有一个关于Java中代码重新排序和竞争条件的问题。 假设我有以下代码,有2个或多个线程同时执行: JVM是否可能以错误的顺序执行此操作?例如,以下重新排序是否可能?: 还是保证锁不会被重新排序?

  • 这似乎很明显,但我之所以这么问,是因为我看到一些自定义验证器检查要验证的值是否为null,如果为null,则返回true。这似乎是个坏主意,因为如果开发人员忘记将添加到字段,那么email字段仍将通过验证。 奥勒蒂亚

  • 我正在使用Laravel5.7和MySQL。我有一个表和一个表,其中包含每个城市中可用的服务。可以在1个或多个城市提供1项服务。每个城市属于一个州,每个州属于一个国家。我想返回服务、城市、州和国家,但我不确定如何在每个模型中建立关系。我可以检索城市、州和国家吗? 城市 国家 国家 服务 允许的位置 国家id,名称1,美国 国家 城市 服务 允许的位置 services.php模型 cities.p

  • 主要内容:JAVA钩子OrientDB钩子类似于数据库术语中的触发器,它在用户应用程序中的每个CRUD操作之前和之后启用内部事件。可以使用挂钩编写自定义验证规则,强制执行安全性,或安排外部事件,例如针对关系DBMS进行复制。 OrientDB支持两种钩子 - 动态钩子 - 触发器,可以在类级别和/或文档级别构建。 Java(Native)钩子 - 触发器,可以使用Java类构建。 动态钩子 动态钩子比Java钩子更灵活