开发者

How to build ElementCollection of Embeddable type?

开发者 https://www.devze.com 2023-02-16 11:35 出处:网络
I\'m using Hibernate 3.5.6 as my JPA 2.0 implementation. I\'m attempting to build an @ElementCollection inside my entity (many fields omitted):

I'm using Hibernate 3.5.6 as my JPA 2.0 implementation. I'm attempting to build an @ElementCollection inside my entity (many fields omitted):

@Entity
public class Buyer implements Serializable {
    ...
    @ElementCollection
    private List<ContactDetails> contacts;
    ...
}
开发者_如何学运维

I've made this work quite easily when the collection contains a basic type, but my ContactDetails is an @Embeddable class:

@Embeddable
public class ContactDetails implements Serializable {
    ...
    @Column(nullable = false)
    private String streetOne;
    ....
}

When I run let Hibernate generate the DDL, I get errors like this:

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

Is there a way to persuade Hibernate to generate valid column names in the table for the collection class? Ideally, a way that doesn't violate the Don't Repeat Yourself principle by specifying each individual column name.


It's a bug in Hibernate caused by incompatibility of DefaultComponentSafeNamingStrategy with @ElementCollection implementation details.

.collection&&element. is an internal placeholder that should be removed before use of property name as a column name. Other naming strategies effectively remove it by using only the part of property name after the last ., whereas DefaultComponentSafeNamingStrategy replaces .s with _s but doesn't remove the placeholder.

If you actually need DefaultComponentSafeNamingStrategy, here is a workaround:

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

Reported: HHH-6005.


Alternative workaround using @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>();


We have just released Batoo JPA, the new implementation of Java Persistence API spec 1.0 & 2.0, with the performance being the main focus. It is over 15x times faster then Hibernate. The project website is http://batoo.jp

I have tried your case against Batoo JPA and it runs just fine. You may also check the unit tests for @ElementCollection in BAtoo JPA here.

Regards.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号