简体   繁体   English

休眠:使用复杂对象的集合会引发异常

[英]Hibernate: Using collection of complex objects throws exceptions

I am looking into Hibernate and storing collections of complex types. 我正在研究Hibernate,并存储复杂类型的集合。 But I run into exception. 但是我遇到了例外。

I have the following persistent class: 我有以下持久性课程:

public class Item {

    private Long id;
    private Set images = new HashSet();
    private Collection<Data> data = new ArrayList<Data>();

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Set getImages() {
        return images;
    }
    public void setImages(Set images) {
        this.images = images;
    }
    public Collection<Data> getData() {
        return data;
    }
    public void setData(Collection<Data> data) {
        this.data = data;
    }
}

The Data class is as follows: 数据类如下:

public class Data {

  private String firstName;
  private String lastName;
  public String getFirstName() {
    return firstName;
  }
  public void setFirstName(String firstName) {
    this.firstName = firstName;     
  }
  public String getLastName() {
    return lastName;
  }
  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
  @Override
   public boolean equals(Object obj) {
    if(!(obj instanceof Data) )
        return false;
    Data d = (Data) obj;
    if(d.firstName.equals(firstName) && d.lastName.equals(lastName))
        return true;
    return false;
  }
 @Override
 public int hashCode() {
    int result;
    result = 17;
    result = 31 * result + firstName.hashCode();
    result = 31 * result + lastName.hashCode();
    return result;
}

The mapping files are as follows: 映射文件如下:
For Item class: 对于商品类:

<hibernate-mapping>
    <class name="com.entities.Item" table="ITEM">
        <id name="id" type="java.lang.Long">
            <column name="ID" />
            <generator class="identity" />
        </id>
        <set name="images" table="ITEM_IMAGE" inverse="false" lazy="true">
            <key>
                <column name="ID" />
            </key>
            <element type="string">
                <column name="IMAGES" />
            </element>
        </set>
        <bag name="data" table="DATA" inverse="false" lazy="true">
            <key>
                <column name="ID" />
            </key>
            <one-to-many class="com.entities.Data" />
        </bag>
    </class>
</hibernate-mapping>

For Data class: 对于数据类:

<hibernate-mapping>
    <class name="com.entities.Data" table="DATA">    
        <id name="firstName" type="java.lang.String">
            <column name="FIRSTNAME" />
            <generator class="assigned" />
        </id>
        <property name="lastName" type="java.lang.String">
            <column name="LASTNAME" />
        </property>
    </class>
</hibernate-mapping>

In my code to save data to MySQL: 在我的将数据保存到MySQL的代码中:

Transaction tx = session.beginTransaction();
Item item = new Item();
Set images = new HashSet();
images.add("C:\\");
images.add("D:\\");
item.setImages(images);
List<Data> data = new ArrayList<Data>();
Data a = new Data();
a.setFirstName("John");
a.setLastName("Smith");
data.add(a);
item.setData(data);
session.save(item);
tx.commit();//-->Exception here
session.close();

I get the following exception on tx.commit(); 我在tx.commit();上收到以下异常tx.commit();

Hibernate: insert into ITEM values ( ) Hibernate: insert into ITEM_IMAGE (ID, IMAGES) values (?, ?) Hibernate: insert into ITEM_IMAGE (ID, IMAGES) values (?, ?) Hibernate: update DATA set ID=? 休眠:插入ITEM值()休眠:插入ITEM_IMAGE(ID,IMAGES)值(?,?)休眠:插入ITEM_IMAGE(ID,IMAGES)值(?,?)休眠:更新数据集ID =? where FIRSTNAME=? 其中FIRSTNAME =? Hibernate: update DATA set ID=? 休眠:更新数据集ID =? where FIRSTNAME=? 其中FIRSTNAME =? 1454 [main] ERROR org.hibernate.jdbc.AbstractBatcher - Exception executing batch: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; 1454 [main]错误org.hibernate.jdbc.AbstractBatcher-执行批处理的异常:org.hibernate.StaleStateException:批处理更新从更新[0]返回意外行数; actual row count: 0; 实际行数:0; expected: 1 at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85) at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70) at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:188) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133) at com.entiti 预期值:org.hibernate.jdbc.BatchingBatcher的org.hibernate.jdbc.Expectations $ BasicExpectation $ BasicExpectation.verifyOutcome(Expectations.java:70)的org.hibernate.jdbc.Expectations $ BasicExpectation.checkBatched(Expectations.java:85)处为1。在org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)在org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)处的checkRowCounts(BatchingBatcher.java:90)在org.hibernate.engine.ActionQueue处org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:188)在org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)处的.executeActions(ActionQueue.java:268)。在org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)在org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)处的event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) .hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)位于com.entiti es.Main.main(Main.java:44) es.Main.main(Main.java:44)

Why do I get this exception? 为什么会出现此异常?
If I remove the Collection<Data> data to store only the Set the code works and the data are saved in MySQL. 如果我删除Collection<Data> data以仅存储Set该代码有效,并且数据保存在MySQL中。

Note: The mapping files have been created by Eclipse Hibernate plugin. 注意:映射文件是由Eclipse Hibernate插件创建的。

Made the following changes to your code : 对您的代码进行了以下更改:

Transaction tx = session.beginTransaction();
Item item = new Item();
//added save here to attach the object to persistance context.
// (This might be optional)
session.save(item);              

Set images = new HashSet();
images.add("C:\\");
images.add("D:\\");
item.setImages(images);           
List<Data> data = new ArrayList<Data>();
Data a = new Data();
a.setFirstName("John");
a.setLastName("Smith");
//added save here to attach the object to persistance context.
//this is required without cascading settings
session.save(a)                 

data.add(a);
item.setData(data);
session.save(item);
tx.commit();//-->Exception here
session.close();

You could otherwise set appropriate the cascading options on the bag! 否则,您可以在袋子上设置适当的层叠选项!

AFAIK you are getting the error since you are trying to persist an association without the other entity (Data) being in persistant state and the cascading options are set to none by default. AFAIK,您收到此错误,是因为您尝试在没有其他实体(数据)处于持久状态的情况下保持关联并且默认情况下将级联选项设置为none。 Again I haven't tried out to run my piece of snippet but this will point you in the right direction. 再次,我没有尝试运行我的片段,但这将为您指明正确的方向。


UPDATE from the OP: 从OP更新:

The problem is solved by using inverse="true" , doing cascade and also I have to reference from Data to Item otherwise the FK column is not updated 通过使用inverse="true"进行cascade解决了问题,而且我还必须从Data引用到Item否则FK列不会更新

可能是由于您向列表data添加a两次的事实?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM