hibernate - 为什么 OneToMany 关系会保存在数据库的多行中

标签 hibernate jpa concurrency akka one-to-many

我有一个 hibernate 实体类

public class MyComplexClass implements  Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    String name;
    int number;
    @ElementCollection
    Map<String,String> myMap;

    @ManyToOne
    Simple simple;

    public MyComplexClass(String name, int number, Map<String,String> myMap) {
        this.name = name;
        this.port = number;
        this.myMap = myMap;
    }

    public MyComplexClass() {
        // TODO Auto-generated constructor stub
    }

    public void setName(String name) {
        this.name = name;

    }

    public String getName() {
        return name;
    }

    public void setNumber(int number) {
        this.port = number;
    }

    public int getPort() {
        return port;
    }

    public void setMyMap(Map<String,String> myMap) {
        this.myMap = myMap;
    }

    public Map<String,String> getMyMap() {
        return this.myMap;
    }


    public Simple getSimple() {
        return this.simple;
    }

在 simple 类中,我有一个表单的映射

    @Entity
    @Table(name = "Simple")


    public class Simple  implements Comparable<Simple>, Serializable {
    @JsonProperty
    @OneToMany(mappedBy="simple",fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    Set<MyComplexClass> myComplexClass;

    public void setMyComplexClass(List<MyComplexClass> myComplexClass) {
        this.myComplexClass = myComplexClass;
    }

    public List<MyComplexClass> getMyComplexClass() {
        return this.myComplexClass;
    }

在系统中的某个位置我将值设置为

Map<String, String> myMap = new HashMap<String,String>();
myMap.put("value","value");
MyComplexClass myComplexClass = new MyComplexclass("a", 123, myMap)
Set<MyComplexClass> myComplexClassList = new HashSet<MyComplexClass>();
myComplexClassList.add(myComplexClassList)
simple.setMyComplexClass(myComplexClassList);
myComplexClass.setSimple(simple);
// save to the database
dao.save(simple);

这会持久保存在数据库中,其中复杂类的多行与简单类的外键相同

 Table: MyComplexClass
    id  name number simple_id
     1  abc   234    1
     2  abc   234    1
     3  abc   234    1
     4  abc   234    1
     5  abc   234    1
     6  xyz   432    2
     7  xyz   432    2
     8  xyz   432    2

我错过了什么?所有这些行的 id 都是不同的,这让我认为它们在代码中已被初始化多次。但他们不是。他们有不同的条目有什么原因吗?我正在使用 AKKA Actor ,这可能是一个原因吗?

基于各种类似的问题。我已将 Collection 更改为 Set,并添加了一个 CompareTo 方法,如下所示

public int compareTo(MyComplexClass o) {
        if (o == null) {
            return 1;
        }

        if (this.getName().equals(o.getName()) && this.getNumber() == o.getPort()) {
            return 0;
        }
        return (int) (id - o.id);
    }

最佳答案

如果可以的话,我会投票关闭这个无法编译且不完整的示例,但由于它有赏金,所以我不能。您引用了一个不包含源代码的 dao 对象。你调用doa.save,这是一个Spring问题吗?否则,您的实体没有任何问题,这对我来说一切都很好。

public class JPAExample {    
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence");
        EntityManager em = emf.createEntityManager();
        try {
            EntityTransaction tx = em.getTransaction();
            tx.begin();
            Simple simple = new Simple();
            Map<String, String> myMap = new HashMap<String,String>();
            myMap.put("value","value");
            MyComplexClass myComplexClass = new MyComplexClass("a", 123, myMap);
            Set<MyComplexClass> myComplexClassList = new HashSet<MyComplexClass>();
            myComplexClassList.add(myComplexClass);
            simple.setMyComplexClass(myComplexClassList);
            myComplexClass.setSimple(simple);
            // save to the database
            em.persist(simple);
            tx.commit();
        } finally {
            emf.close();
        }
    }
}

简单类

@Entity
@Table(name = "Simple")
public class Simple implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) Long id;
    //    @JsonProperty
    @OneToMany(mappedBy = "simple", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    Set<MyComplexClass> myComplexClass;
    public void setMyComplexClass(Set<MyComplexClass> myComplexClass) {
        this.myComplexClass = myComplexClass;
    }
    public Set<MyComplexClass> getMyComplexClass() {
        return this.myComplexClass;
    }
}

我的复杂类

@Entity
@Table(name="MyComplexClass")
public class MyComplexClass implements  Serializable {
    private static final long serialVersionUID = 1L;
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) Long id;
    String name;
    int number;
    @ElementCollection
    Map<String,String> myMap;
    @ManyToOne
    Simple simple;
    public MyComplexClass(String name, int number, Map<String,String> myMap) {
        this.name = name;
        this.myMap = myMap;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setMyMap(Map<String,String> myMap) {
        this.myMap = myMap;
    }
    public Map<String,String> getMyMap() {
        return this.myMap;
    }
    public Simple getSimple() {
        return this.simple;
    }
    public void setSimple(Simple simple ) {
        this.simple = simple;
    }
}

产生以下输出...

Hibernate: create table MyComplexClass (id bigint generated by default as identity (start with 1), name varchar(255), number integer not null, simple_id bigint, primary key (id))
Hibernate: create table MyComplexClass_myMap (MyComplexClass_id bigint not null, myMap varchar(255), myMap_KEY varchar(255), primary key (MyComplexClass_id, myMap_KEY))
Hibernate: create table Simple (id bigint generated by default as identity (start with 1), primary key (id))
Hibernate: alter table MyComplexClass add constraint FK_qlkwvh7xyrn3udhnrn40fl6f8 foreign key (simple_id) references Simple
Hibernate: alter table MyComplexClass_myMap add constraint FK_qp5xa90y7pk94lb64kvt62589 foreign key (MyComplexClass_id) references MyComplexClass
Jun 12, 2017 10:06:56 AM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
Hibernate: insert into Simple (id) values (default)
Hibernate: insert into MyComplexClass (id, name, number, simple_id) values (default, ?, ?, ?)
Hibernate: insert into MyComplexClass_myMap (MyComplexClass_id, myMap_KEY, myMap) values (?, ?, ?)
Jun 12, 2017 10:06:56 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:hsqldb:mem:standalone]

这仅显示插入到 MyComplexClass 表中的一行。

您可以复制此代码并使用它来找出代码的问题所在。

关于hibernate - 为什么 OneToMany 关系会保存在数据库的多行中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44461194/

相关文章:

java - 如何更新 Spring WebFlow 模型中的数据并将其传递回同一 View

java.lang.AssertionError : org. hibernate.exception.SQLGrammarException:无法插入:

go - 从 api 同时请求数据时 TLS 握手超时

Java map : multithreading juggler

Java - 找不到符号类并发

java - 通过 Hibernate 的 org.hibernate.Query 将 Clob 数据加载为字符串(eager)

java.lang.NoSuchMethodException : Unknown property 'language' on class 'class java.lang.Class'

SQL 语句中的 Spring Boot Hibernate 语法错误

java - 如何删除被其他对象引用的对象?

java - 使用 AccessType.PROPERTY 对 JPA 实体属性调用清除失败