【问题标题】:How to build ElementCollection of Embeddable type?如何构建 Embeddable 类型的 ElementCollection?
【发布时间】:2011-03-11 14:42:26
【问题描述】:

我使用 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;
    ....
}

当我运行 let 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 在表中为集合类生成有效的列名?理想情况下,通过指定每个单独的列名称,不违反 Don't Repeat Yourself 原则的方式。

【问题讨论】:

    标签: java hibernate jpa-2.0


    【解决方案1】:

    这是由于DefaultComponentSafeNamingStrategy@ElementCollection 实现细节不兼容而导致的Hibernate 错误。

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

    如果您确实需要DefaultComponentSafeNamingStrategy,这里有一个解决方法:

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

    举报:HHH-6005

    【讨论】:

    • 根据错误跟踪器,这已在 Hibernate 5 中修复。
    • 我花了几个小时才找到它。错误消息很好地隐藏了整个 ddl 日志。谢谢!
    【解决方案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>();
    

    【讨论】:

      【解决方案3】:

      我们刚刚发布了 Batoo JPA,它是 Java Persistence API 规范 1.0 和 2.0 的新实现,性能是主要关注点。它比 Hibernate 快 15 倍以上。项目网址是http://batoo.jp

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

      问候。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-25
        • 1970-01-01
        • 2013-05-06
        • 1970-01-01
        • 2012-08-12
        • 2013-04-17
        • 2012-08-21
        • 1970-01-01
        相关资源
        最近更新 更多