2013-06-10 5 views
0

У меня возникла проблема повторного использования записей, чтобы заполнить таблицу перекрестных ссылок. Hibernate пытается обновить записи внешнего ключа, а не заполнять таблицу перекрестных ссылок.Hibernate many-to-many - Не удалось выполнить пакетное обновление JDBC

Вставка новых записей работает нормально.

DB Диаграмма enter image description here

Когда я добавляю новые места и соединить их в таблице перекрестных ссылок, он работает без каких-либо проблем:

//Get specific object 
TestContainer tc = (TestContainer) session.createQuery("from TestContainer where id = :id") 
     .setParameter("id", id).list().get(0); 

//Locations 
Set<TestContainerLocation> tcl = new HashSet<TestContainerLocation>(); 

TestContainerLocation loc1 = new TestContainerLocation(); 
loc1.setLocationName("String1"); 
TestContainerLocation loc2 = new TestContainerLocation(); 
loc2.setLocationName("String2"); 

tcl.add(loc1); 
tcl.add(loc2); 

tc.setTestContainerLocation(tcl); 

session.saveOrUpdate(tc); 

При попытке повторно использовать существующие места, то его не проходит. Вместо того, чтобы вставлять в таблицу перекрестных ссылок, он пытается обновить таблицу внешнего ключа, предоставив нулевое значение, которое не выполняется из-за ограничений.

//Get specific object 
TestContainer tc = (TestContainer) session.createQuery("from TestContainer where id = :id") 
     .setParameter("id", id).list().get(0); 

Set<TestContainerLocation> tcl = new HashSet<TestContainerLocation>(); 

TestContainerLocation loc1 = new TestContainerLocation(); 
loc1.setLocationId(1);//existing Id 
TestContainerLocation loc2 = new TestContainerLocation(); 
loc2.setLocationId(2);//existing Id 

tcl.add(loc1); 
tcl.add(loc2); 

tc.setTestContainerLocation(tcl); 

session.saveOrUpdate(tc); 

Ошибка:

Hibernate: select testcontai0_.id as id0_, testcontai0_.step_one as step2_0_, testcontai0_.step_two as step3_0_, testcontai0_.step_three as step4_0_, testcontai0_.type_id as type5_0_ from test_container testcontai0_ where testcontai0_.id=? 
Hibernate: update test_container_location set location_name=? where location_id=? 
Hibernate: update test_container_location set location_name=? where location_id=? 
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 
... 
Caused by: java.sql.BatchUpdateException: Column 'location_name' cannot be null 

ОТОБРАЖЕНИЯ

TestContainer.hbm.xml

<class name="TestContainer" 
    table="test_container"> 
    <id name="id" column="id" type="long" unsaved-value="null"> 
     <generator class="identity"></generator> 
    </id> 

    <property name="stepOne" type="string" length="255" column="step_one" not-null="false" /> 
    <property name="stepTwo" type="integer" column="step_two" not-null="false" /> 
    <property name="stepThree" type="string" length="255" column="step_three" not-null="false" /> 

    <many-to-one name="testContainerType" class="org.test.data.TestContainerType" fetch="select"> 
     <column name="type_id" not-null="true"/> 
    </many-to-one> 

    <set name="testContainerLocation" table="test_container_location_lookup" 
    inverse="false" lazy="true" fetch="select" cascade="all"> 
     <key> 
      <column name="id" not-null="true"/> 
     </key> 
     <many-to-many entity-name="org.test.data.TestContainerLocation"> 
      <column name="location_id" not-null="true" /> 
     </many-to-many> 
    </set> 

</class>  

TestContainerLocation.hbm.xml

<class name="TestContainerLocation" 
     table="test_container_location"> 
     <id name="locationId" column="location_id" type="integer" unsaved-value="null"> 
      <generator class="identity"></generator> 
     </id> 
     <property name="locationName" type="string" length="255" column="location_name" not-null="false" /> 

     <set name="testContainer" table="test_container_location_lookup" 
     inverse="true" lazy="true" fetch="select" cascade="all"> 
      <key> 
       <column name="location_id" not-null="true"/> 
      </key> 
      <many-to-many entity-name="org.test.data.TestContainer"> 
       <column name="id" not-null="true" /> 
      </many-to-many> 
     </set> 
    </class>  
+0

Вы не обновляя название места, связанное с 'location_name' столбца в базе данных, которая является обязательной. – Lion

+0

@Lion, так как я устанавливаю идентификатор, который я хочу, почему он делает обновление таблицы внешних ключей? Не следует ли просто добавлять записи в таблицу перекрестных ссылок? – TekiusFanatikus

ответ

0

Использовать session.get() или load() вместо new TestContainerLocation(). Например:

TestContainerLocation loc1 = (TestContainerLocation) session.load(TestContainerLocation.class, 1);  

EDIT: Hibernate пытается обновить TestContainerLocation объект при использовании new(), а затем установить идентификатор.

+0

спасибо за помощь! – TekiusFanatikus

0

this error coused by your default string size character
you have two choice for solve this problem
1.you must up string character size
example

<property name="companyname" column="company_name" length='25' /> 

your companyname size must little than 25
2. change type to text example

<property name="companyname" column="company_name" type='text' />