如何构建Embeddable类型的ElementCollection?

时间:2011-03-11 14:42:27

标签: java hibernate jpa-2.0

我正在使用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在集合类的表中生成有效的列名?理想情况下,通过指定每个列名称,这种方式不会违反不要重复自己原则。

3 个答案:

答案 0 :(得分:12)

由于DefaultComponentSafeNamingStrategy@ElementCollection实施细节不兼容而导致Hibernate出现错误。

.collection&&element.是一个内部占位符,在将属性名称用作列名之前应将其删除。其他命名策略通过在最后.之后仅使用属性名称的一部分来有效地删除它,而DefaultComponentSafeNamingStrategy.替换_但不删除占位符

如果您确实需要DefaultComponentSafeNamingStrategy,则可以采用以下解决方法:

public class FixedDefaultComponentSafeNamingStrategy extends DefaultComponentSafeNamingStrategy {
    @Override
    public String propertyToColumnName(String propertyName) {
        return super.propertyToColumnName(
            propertyName.replace(".collection&&element.", "."));
    }
}

报告:HHH-6005

答案 1 :(得分: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", column=@Column(name="personId")),
    @AttributeOverride(name="placeRoleId", column=@Column(name="placeRoleId"))
})
private Set<PlaceMember> members = new HashSet<PlaceMember>();

答案 2 :(得分:-6)

我们刚刚发布了Batoo JPA,这是Java Persistence API规范1.0&amp; 2.0,以性能为主要焦点。它比Hibernate快15倍以上。项目网站是http://batoo.jp

我已经尝试过针对Batoo JPA的案子,它运行得很好。您还可以在BAtoo JPA here中检查@ElementCollection的单元测试。

问候。