Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
Hi,
We've got some troubles mapping multiple multilingual fields in a single table. Basically what we're trying to do is mapping an entity (Accommodation is this case) that has some single language properties and some other multilanguage properties that are stored in a Map<Language, String> object. All single language properties are stored in a table of its own, while all multilingual fields are stored together in a separate table using a composite key:
table accommodation
Code:
+---------+--------------+------+-----+
| Field | Type | Null | Key |
+---------+--------------+------+-----+
| id | bigint(20) | NO | PRI |
| comment | varchar(255) | YES | |
+---------+--------------+------+-----+
table accommodation_i18n
Code:
+------------------+--------------+------+-----+
| Field | Type | Null | Key |
+------------------+--------------+------+-----+
| accommodation_id | bigint(20) | NO | PRI |
| language_id | varchar(3) | NO | PRI |
| name | varchar(255) | YES | |
| description | varchar(255) | YES | |
| openingPeriod | varchar(255) | YES | |
+------------------+--------------+------+-----+
Language is an entity that's mapped in it's own table that looks like this:
Code:
+-----------------+--------------+------+-----+
| Field | Type | Null | Key |
+-----------------+--------------+------+-----+
| isoLanguageCode | varchar(3) | NO | PRI |
| language | varchar(255) | YES | |
+-----------------+--------------+------+-----+
When persisting the objects using the mapping below, it seems like Hibernate performs an insert for every multilingual field that it encounters. Eventually, this results in a org.hibernate.exception.ConstraintViolationException as the composite primary key already exists after the first multilingual field has been persisted.
Is there a way to make Hibernate perform updates after the first lingual field, or even better do a single insert with all multilingual fields in one statement?
Any help appreciated,
Frederik
Hibernate version: 3.2.0.ga
Mapping documents:Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="be.tvl.tpm2.domain">
<class name="Accommodation">
<id name="id" type="long" unsaved-value="null">
<generator class="native" />
</id>
<property name="comment" />
<map name="name" table="accommodation_i18n" access="field">
<key column="accommodation_id" not-null="true" />
<map-key-many-to-many column="language_id"
class="be.tvl.tpm2.domain.Language" />
<element type="string" column="name" />
</map>
<map name="description" table="accommodation_i18n" access="field">
<key column="accommodation_id" not-null="true" />
<map-key-many-to-many column="language_id"
class="be.tvl.tpm2.domain.Language" />
<element type="string" column="description" />
</map>
<map name="openingPeriod" table="accommodation_i18n" access="field">
<key column="accommodation_id" not-null="true" />
<map-key-many-to-many column="language_id"
class="be.tvl.tpm2.domain.Language" />
<element type="string" column="openingPeriod" />
</map>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
Language dutch = (Language) session.load(Language.class, "dut");
Language english = (Language) session.load(Language.class, "eng");
Hotel hotel = new Hotel();
hotel.setName("Ibis Brussels off Grand Place");
hotel.setAddress(new Address("Grasmarkt", "100", null, "1000", "BRUSSELS", "BELGIUM"));
hotel.setFacilities(dutch, new HotelFacilities("Speeltuin", "Golfterrein"));
hotel.setFacilities(english, new HotelFacilities("Playground", "Gulf course"));
Accommodation accommodation = new Accommodation();
accommodation.setComment("commentaar");
accommodation.setDescription(dutch, "Nederlandse omschrijving");
accommodation.setName(dutch, "Nederlandse naam");
accommodation.setOpeningPeriod(dutch, "nu");
accommodation.setDescription(english, "English description");
accommodation.setName(english, "English name");
accommodation.setOpeningPeriod(english, "now");
hotel.setAccommodation(accommodation);
Transaction tx = session.beginTransaction();
session.save(hotel);
tx.commit();
Full stack trace of any exception that occurs:Code:
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:92)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:87)
at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:218)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1119)
at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:26)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:143)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at be.tvl.tpm2.main.InitHoteli18n.initHotel(InitHoteli18n.java:59)
at be.tvl.tpm2.main.InitHoteli18n.main(InitHoteli18n.java:22)
Caused by: java.sql.BatchUpdateException: Duplicate entry '2-dut' for key 1
at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:648)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
... 15 more
Name and version of the database you are using: mysql Ver 14.12 Distrib 5.0.22, for Win32 (ia32)
The generated SQL (show_sql=true):Hibernate: insert into Accommodation (comment) values (?)
Hibernate: insert into Hotel (name, street, houseNumber, poBox, zipCode, city, country, accommodation) values (?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into HotelFacilities (childrenFacilities, otherSports, hotel_id, language_id) values (?, ?, ?, ?)
Hibernate: insert into HotelFacilities (childrenFacilities, otherSports, hotel_id, language_id) values (?, ?, ?, ?)
Hibernate: insert into accommodation_i18n (accommodation_id, language_id, name) values (?, ?, ?)
Hibernate: insert into accommodation_i18n (accommodation_id, language_id, name) values (?, ?, ?)
Hibernate: insert into accommodation_i18n (accommodation_id, language_id, description) values (?, ?, ?)
Hibernate: insert into accommodation_i18n (accommodation_id, language_id, description) values (?, ?, ?)
Debug level Hibernate log excerpt:Problems with Session and transaction handling?
Read this:
http://hibernate.org/42.htmlCode:
Code: