Как создать ElementCollection встраиваемого типа?
Я использую Hibernate 3.5.6 в качестве своей реализации JPA 2.0. Я пытаюсь построить @ElementCollection
внутри моей сущности (многие поля опущены):
@Entity
public class Buyer implements Serializable {
...
@ElementCollection
private List<ContactDetails> contacts;
...
}
Я сделал эту работу довольно легко, когда коллекция содержит базовый тип, но мой ContactDetails
- это класс @Embeddable
:
@Embeddable
public class ContactDetails implements Serializable {
...
@Column(nullable = false)
private String streetOne;
....
}
Когда я запускаю, пусть Hibernate генерирует DDL, я получаю такие ошибки:
INFO - Environment - Hibernate 3.5.6-Final
....
INFO - Version - Hibernate EntityManager 3.5.6-Final
....
INFO - SettingsFactory - RDBMS: PostgreSQL, version: 8.4.2
INFO - SettingsFactory - JDBC driver: PostgreSQL Native Driver, version: PostgreSQL 9.0 JDBC4 (build 801)
INFO - Dialect - Using dialect: org.hibernate.dialect.PostgreSQLDialect
....
ERROR - SchemaUpdate - Unsuccessful: create table Buyer_contacts (Buyer_id int8 not null, contacts_collection&&element_county varchar(255), contacts_collection&&element_email varchar(255), contacts_collection&&element_fax varchar(255), contacts_collection&&element_mainphone varchar(255) not null, contacts_collection&&element_mobile varchar(255), contacts_collection&&element_name varchar(255) not null, contacts_collection&&element_postcode varchar(255) not null, contacts_collection&&element_streetone varchar(255) not null, contacts_collection&&element_streettwo varchar(255), contacts_collection&&element_town varchar(255) not null)
ERROR - SchemaUpdate - ERROR: syntax error at or near "&&" Position: 73
Есть ли способ убедить Hibernate генерировать правильные имена столбцов в таблице для класса коллекции? В идеале, способ, который не нарушает принцип "Не повторяйте себя", указывая каждое имя каждого столбца.
Ответы
Ответ 1
Это ошибка в Hibernate, вызванная несовместимостью DefaultComponentSafeNamingStrategy
с деталями реализации @ElementCollection
.
.collection&&element.
является внутренним заполнителем, который следует удалить перед использованием имени свойства в качестве имени столбца. Другие стратегии именования эффективно удаляют его, используя только часть имени свойства после последнего .
, тогда как DefaultComponentSafeNamingStrategy
заменяет .
на _
, но не удаляет местозаполнитель.
Если вам действительно нужно DefaultComponentSafeNamingStrategy
, вот обходной путь:
public class FixedDefaultComponentSafeNamingStrategy extends DefaultComponentSafeNamingStrategy {
@Override
public String propertyToColumnName(String propertyName) {
return super.propertyToColumnName(
propertyName.replace(".collection&&element.", "."));
}
}
Сообщено: HHH-6005.
Ответ 2
Альтернативное обходное решение с использованием @AttributeOverrides
:
/**
* <!-- begin-user-doc --> <!-- end-user-doc --> <!-- begin-model-doc -->
* User assignments (place managers, staffs, etc.). <!-- end-model-doc -->
*
*/
@ElementCollection()
// Workaround for https://hibernate.atlassian.net/browse/HHH-6005
@AttributeOverrides({
@AttributeOverride(name="personId", [email protected](name="personId")),
@AttributeOverride(name="placeRoleId", [email protected](name="placeRoleId"))
})
private Set<PlaceMember> members = new HashSet<PlaceMember>();
Ответ 3
Мы только что выпустили Batoo JPA, новую реализацию API Java Persistence API 1.0 и 2.0, причем основной задачей является производительность. Это более чем в 15 раз быстрее, чем Hibernate. Веб-сайт проекта http://batoo.jp
Я пробовал ваше дело против Batoo JPA, и он работает отлично. Вы также можете проверить модульные тесты для @ElementCollection в BAtoo JPA здесь.
С уважением.