2011-09-29 57 views
0

我正在研究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; 
    } 
} 

数据类如下:

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

的映射文件如下:
对于项目类:

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

休眠以下异常:插入项目values()Hibernate:插入到 ITEM_IMAGE(ID,IMAGES)values(?,?)Hibernate :插入到 ITEM_IMAGE(ID,IMAGES)值(?,?)休眠:更新数据集ID =? FIRSTNAME =?休眠:更新数据集ID =? FIRSTNAME =? 1454 [main] ERROR org.hibernate.jdbc.AbstractBatcher - 异常 正在执行批处理:org.hibernate.StaleStateException:批更新 返回来自update [0]的意外行计数;实际行数:0; 预期:1在 org.hibernate.jdbc.Expectations $ BasicExpectation.checkBatched(Expectations.java:85) 在 org.hibernate.jdbc.Expectations $ BasicExpectation.verifyOutcome(Expectations.java:70) 在 组织。 hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90) 在 org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) 在 org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java: 268) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268) at org.hibernate.engine.ActionQueue.executeActions(Ac tionQueue.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)at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java: 133.) at com.entities.main.main(Main.java:44)

为什么我会得到这个异常?
如果我删除Collection<Data> data以仅存储Set,代码将工作,数据将保存在MySQL中。

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

回答

1

作了如下修改代码:

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由于您试图在没有其他实体(数据)处于持续状态并且级联选项默认设置为none的情况下试图保持关联,您会收到错误。再次,我没有尝试过运行我的一小段代码,但这会让你指向正确的方向。从OP


UPDATE:

的问题通过使用inverse="true",做cascade,也是我必须引用从DataItem否则FK列不更新

+0

+ 1.我实际上必须做'session.save(a)'来工作。我假设我不希望我循环在列表中保存每个'Data'对象。 – Cratylus

+0

我的意思是,因为您没有使用级联,所以您需要将子实体附加到持久性上下文中。如果您添加多个数据对象,则可以保存每个数据对象。为了避免这个额外的电话尝试使用级联[请参阅:http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-parentchild.html] – frictionlesspulley

+0

链接不工作 – Cratylus

0

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

+0

都能跟得上解决。我删除了第二个''添加'列表,并得到了相同的异常。我更新了这个帖子,尽量不要混淆 – Cratylus