为什么OneToMany关系在数据库中的多行中保持不变

时间:2017-06-09 15:09:18

标签: 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;
    }

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

    @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演员,这可能是一个原因吗?

基于各种类似的问题。我已将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);
    }

2 个答案:

答案 0 :(得分:0)

我投票决定关闭这个不编译的例子,如果可以的话就不完整,但因为它有赏金我不能。您引用了一个不包含source的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();
        }
    }
}

Simple.class

@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;
    }
}

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表。

您可以复制此代码并使用它来确定您的代码有什么问题。

答案 1 :(得分:0)

由于您使用的是基于哈希的集合Set,因此您必须覆盖equals实体中的hashcodeMyComplexClass

来自docs

  

如果您执行以下操作,则必须覆盖equals()和hashCode()方法:    打算将持久化类的实例放在一个Set中(推荐的表示多值关联的方式);和   打算使用重新附加分离的实例

覆盖equalshashcode可以解决您的问题。