Hibernate: использование коллекции сложных объектов вызывает исключения - PullRequest
0 голосов
/ 30 сентября 2011

Я изучаю 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();

Hibernate: вставить в значения ITEM () Hibernate: вставить в значения Значения ITEM_IMAGE (ID, IMAGES) (?,?) Hibernate: вставить в ITEM_IMAGE (ID, IMAGES) значения (?,?) Hibernate: обновить ID набора данных =? где FIRSTNAME =? Hibernate: обновить 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<Data> data для хранения только Set, код работает, и данные сохраняются в MySQL.

Примечание. Файлы сопоставления созданы плагином Eclipse Hibernate.

Ответы [ 2 ]

1 голос
/ 30 сентября 2011

Внесены следующие изменения в ваш код:

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 вы получаете сообщение об ошибке, так как вы пытаетесь сохранить связь, пока другой объект (Данные) не находится в постоянном состоянии, а параметры каскадирования по умолчанию не установлены.Опять же, я не пытался запустить свой фрагмент кода, но это укажет вам правильное направление.


ОБНОВЛЕНИЕ ОП:

Проблема решается с помощью inverse="true", с помощью cascade, а также я должен ссылаться с Dataна Item в противном случае столбец FK не обновляется

0 голосов
/ 30 сентября 2011

Возможно, это связано с тем, что вы добавляете a в список data дважды?

...