【问题标题】:Hibernate: Using collection of complex objects throws exceptionsHibernate:使用复杂对象的集合会引发异常
【发布时间】:2011-11-28 00:30:28
【问题描述】:

我正在研究 Hibernate 并存储复杂类型的集合。但我遇到了异常。

我有以下持久类:

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

Data类如下:

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

映射文件如下:
对于 Item 类:

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

对于数据类:

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

在我的代码中将数据保存到 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();

tx.commit(); 出现以下异常

Hibernate: 插入 ITEM 值 () Hibernate: 插入 ITEM_IMAGE (ID, IMAGES) 值 (?, ?) Hibernate: 插入 ITEM_IMAGE (ID, IMAGES) 值 (?, ?) Hibernate: update DATA set ID=? FIRSTNAME=?休眠:更新数据集 ID=? FIRSTNAME=? 1454 [main] 错误 org.hibernate.jdbc.AbstractBatcher - 异常 执行批处理:org.hibernate.StaleStateException:批量更新 从更新 [0] 返回意外的行数;实际行数:0; 预期:1 在 org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85) 在 org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70) 在 org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90) 在 org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) 在 org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) 在 org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268) 在 org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:188) 在 org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 在 org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) 在 org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) 在 org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383) 在 org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133) 在 com.entities.Main.main(Main.java:44)

为什么会出现此异常?
如果我删除 Collection&lt;Data&gt; data 以仅存储 Set 代码有效并且数据保存在 MySQL 中。

注意:映射文件是由 Eclipse Hibernate 插件创建的。

【问题讨论】:

    标签: java mysql hibernate jakarta-ee hibernate-mapping


    【解决方案1】:

    可能是因为您将a 添加到列表data 两次?

    【讨论】:

    • 不。我将a 中的第二个add 删除到列表中,但仍然遇到同样的异常。我更新了帖子以免混淆
    【解决方案2】:

    对您的代码进行以下更改:

    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();
    

    您可以在包上设置适当的级联选项!

    AFAIK 您收到错误消息,因为您尝试在其他实体(数据)不处于持久状态的情况下保持关联,并且默认情况下级联选项设置为无。同样,我还没有尝试运行我的 sn-p,但这将为您指明正确的方向。


    来自 OP 的更新:

    问题通过使用inverse="true" 解决,执行cascade 并且我必须从Data 引用到Item 否则FK 列不会更新

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-20
    • 2014-10-12
    • 2019-07-05
    • 2020-03-02
    • 1970-01-01
    • 2011-03-04
    • 2011-10-25
    • 2020-02-04
    相关资源
    最近更新 更多