当前位置: 首页 > 面试题库 >

用于一对多双向映射的Hibernate和H2“违反参考完整性约束”

子车轶
2023-03-14
问题内容

所以我有两个简单的豆子-
FatKid和Hamburgers。现在,出于我不知道的原因,我不仅需要查找某人吃过的所有汉堡包,而且还要查找谁吃了哪个特定的汉堡包。进入代码!

FatKid.java

import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Table
@Entity
public class FatKid {

    private int id;
    private String name;
    private List<Hamburger> hamburgers;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "FATKID_ID")
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    @Column
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name="HAMBURGER_ID")
    public List<Hamburger> getHamburgers() {
        return hamburgers;
    }
    public void setHamburgers(List<Hamburger> hamburgers) {
        this.hamburgers = hamburgers;
    }

}

汉堡包

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Table
@Entity
public class Hamburger {

    private int id;
    private String description;
    private FatKid whoDoneAteMe;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "HAMBURGER_ID")
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    @Column
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="FATKID_ID")
    public FatKid getWhoDoneAteMe() {
        return whoDoneAteMe;
    }
    public void setWhoDoneAteMe(FatKid whoDoneAteMe) {
        this.whoDoneAteMe = whoDoneAteMe;
    }

}

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:~/routesetting</property>
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">create-drop</property>

        <mapping class="FatKid" />
        <mapping class="Hamburger" />

    </session-factory>
</hibernate-configuration>

依存关系

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>3.6.7.Final</version>
</dependency>

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.3.160</version>
</dependency>

<dependency>
    <groupId>javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.9.0.GA</version>
</dependency>

客户

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class OmNom {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    public static void main(String[] args) {

        Session session = sessionFactory.openSession();

        session.beginTransaction();
        FatKid fk = new FatKid();
        fk.setName("Darrell");
        session.save(fk);
        session.getTransaction().commit();

        session.beginTransaction();
        Hamburger hamburger_1 = new Hamburger();
        hamburger_1.setDescription("Juicy quarter pounder with cheese");
        hamburger_1.setWhoDoneAteMe(fk);
        session.save(hamburger_1);
        session.getTransaction().commit();

        session.beginTransaction();
        Hamburger hamburger_2 = new Hamburger();
        hamburger_2.setDescription("Ground buffalo burger topped with bacon and a sunny-side egg");
        hamburger_2.setWhoDoneAteMe(fk);
        session.save(hamburger_2);
        session.getTransaction().commit();

        sessionFactory.close();

    }

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration().configure().buildSessionFactory();
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            throw new ExceptionInInitializerError(ex);
        }
    }

}

因此,当我运行代码时,我最终得到输出(以及截断的堆栈跟踪)

Hibernate: insert into FatKid (FATKID_ID, name) values (null, ?)
Hibernate: insert into Hamburger (HAMBURGER_ID, description, FATKID_ID) values (null, ?, ?)
Hibernate: insert into Hamburger (HAMBURGER_ID, description, FATKID_ID) values (null, ?, ?)
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not insert: [Hamburger]
        ...
Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FK43797FE95067143: PUBLIC.HAMBURGER FOREIGN KEY(HAMBURGER_ID) REFERENCES PUBLIC.FATKID(FATKID_ID)"; SQL statement:
insert into Hamburger (HAMBURGER_ID, description, FATKID_ID) values (null, ?, ?) [23506-160]
        ...

因此,第一个汉堡被保存,但第二个被炸掉。两者都应该能够使用FatKid的ID作为其外键,但似乎不起作用。任何见识将不胜感激。

谢谢,凯文


问题答案:

您的映射对我来说很奇怪。关系的两边都有一个@JoinColumn,每个都指向另一个表的主键。那似乎不是一对多的关系。

您的OneToMany应该告诉关系的所有者:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "whoDoneAteMe")
public List<Hamburger> getHamburgers() {
    return hamburgers;
}

然后在另一边:

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "fatkid_id")
public FatKid getWhoDoneAteMe() {
    return whoDoneAteMe;
}

您也许也可以进一步优化代码。由于您的FatKid对象可以识别Hamburger对象,并且已经配置了级联,因此您可以执行以下操作:

    session.beginTransaction();
    FatKid fk = new FatKid();
    fk.setName("Darrell");

    Hamburger hamburger_1 = new Hamburger();
    hamburger_1.setDescription("Juicy quarter pounder with cheese");
    hamburger_1.setWhoDoneAteMe(fk);
    fk.getHamburgers().add(hamburger1);

    Hamburger hamburger_2 = new Hamburger();
    hamburger_2.setDescription("Ground buffalo burger topped with bacon and a sunny-side egg");
    hamburger_2.setWhoDoneAteMe(fk);
    fk.getHamburgers().add(hamburger2);

    session.save(fk);
    session.getTransaction().commit();

    sessionFactory.close();

上面的代码应仅通过一次提交操作并在单个事务中保存完整的对象图。



 类似资料:
  • 1. 前言 本节课程和大家一起聊聊一对多关联映射。通过本节课程,你将了解到: 如何实现一对多关联映射; 如何实现双向一对多关联映射; 关联映射中的级联操作。 2. 一对多关联映射 关系型数据库中表与表中的数据存在一对多(或多对一)关系。 如学生表、班级表。一个班级有多个学生,多个学生可以在同一个班级。 一对多或多对一本质上是一样的,如同一块硬币的正面和反面,只是看待事物的角度不同而已。 数据库中有

  • 1. 前言 通过本节课程的学习,你将发现关联对象之间的微妙关系。相信这种关系对你更深入地认识 HIbernate 有很大的帮助。 通过本节课程,你将了解到: 多对多双向关联映射中哪一方是关系维系者; 级联操作与关系维系者。 2. 关系维系者 新学期开始了,同学们选择了各自喜欢的课程,现在为学生添加选修课程的任务就要落在 Hibernate 的身上。一起来看看 Hibernate 是如何完成这个任务

  • 问题内容: 我正在尝试解析Web请求并将其保存到数据库。我有3个模型,第一个节点是virtualDocument。这是uniq表(根据请求url)。VirtualRequest表具有所有erquest主体,而HttpHeaderList表根据其virtualRequest bean ID具有所有thhp标头。 当我尝试保存第一个日志时,出现了这样的错误; 这是VirtualDocument bea

  • 照明\database\queryexception SQLSTATE[23000]:完整性约束违反:19 NOT NULL约束失败:users.password(SQL:插入“users”(“name”、“email”、“username”、“updated_at”、“created_at”)值(MADHUP KUMAR,Chandrashivam99@gmail.com,Vansh123,20

  • 我有两张桌子。后 和喜欢 在这些对象之间进行hibernate注释映射,以便在类似于Post bean的。。。。 就像豆子一样 问题 该关联是否由Post{@OneToOne}和like{@ManyToOne}正确? 获取类型是Lazy,但仍然得到依赖循环。为什么? 尝试 要删除依赖关系循环,我尝试了 {@xmltransive} {@JsonIgnore} {@JsonManagedRefere

  • 问题内容: 我正在尝试使用ALTER IGNORE TABLE + UNIQUE KEY从MySQL表中删除重复项。MySQL文档说: IGNORE是标准SQL的MySQL扩展。如果新表中的唯一键上有重复项,或者在启用严格模式时出现警告,则它控制ALTER TABLE的工作方式。如果未指定IGNORE,则在发生重复键错误时,副本将中止并回滚。如果指定了IGNORE,则只有第一行用于唯一键重复的行。