开发者

Is it possible for a JPA embeddable to contain Embeddable or Collection of Embeddables?

开发者 https://www.devze.com 2023-02-15 20:41 出处:网络
I wonder whether it is possible to have an ElementCollection of Embeddable inside another Embeddable ?

I wonder whether it is possible to have an ElementCollection of Embeddable inside another Embeddable ?

Here's an example of my Supplier entity which has a list of Addresses, which is of an embeddable type :

@Entity
public class Supplier extends BaseCommonEntity {
    @Column(unique=true)
    private String supplierCode;    

    private String supplierName;

    @ElementCollection
    private List<Address> addresses;
....

And here's my embeddable Address that co开发者_如何学Cntains a list of embeddable Phone

@Embeddable
public class Address {
    private String address;
    private String city;
    private String country;
    private String postcode;

    @ElementCollection
    private List<Phone> phones;
    public List<Phone> getPhones() {
        return phones;
    }

    public void setPhones(List<Phone> phones) {
        this.phones = phones;
    }
...

And here's the embeddable phone definition

@Embeddable
public class Phone {
    private Long phoneCountryCode;
    private Long phoneCityCode;
    private Long phoneNo;
    private Long faxCountryCode;
    private Long faxCityCode;
    private Long faxNo;
...

Im currently testing this with JPA 2 + Hibernate 3.6.x

Using the embeddable Phone inside the Address results in error in my test. Here's the partial debug messages from the most bottom :

DEBUG PropertyBinder - Building property country
DEBUG Ejb3Column - Binding column: Ejb3JoinColumn{logicalColumnName='null', referencedColumn='null', mappedBy=''}
DEBUG Ejb3Column - Binding column: Ejb3Column{table=org.hibernate.mapping.Table(Supplier_addresses), mappingColumn=phones, insertable=true, updatable=true, unique=false}
DEBUG Ejb3Column - Binding column: Ejb3Column{table=org.hibernate.mapping.Table(Supplier_addresses), mappingColumn=null, insertable=true, updatable=true, unique=false}
DEBUG Ejb3Column - Binding column: Ejb3Column{table=org.hibernate.mapping.Table(Supplier_addresses), mappingColumn=phones, insertable=true, updatable=true, unique=false}
DEBUG Ejb3Column - Binding column: Ejb3Column{table=org.hibernate.mapping.Table(Supplier_addresses), mappingColumn=phones_KEY, insertable=true, updatable=true, unique=false}
DEBUG Ejb3Column - Binding column: Ejb3JoinColumn{logicalColumnName='phones_KEY', referencedColumn='null', mappedBy='null'}
DEBUG Ejb3Column - Binding column: Ejb3JoinColumn{logicalColumnName='null', referencedColumn='null', mappedBy=''}
DEBUG Ejb3Column - Binding column: Ejb3JoinColumn{logicalColumnName='null', referencedColumn='null', mappedBy=''}
DEBUG CollectionBinder - Collection role: com.primetech.core.entity.Supplier.addresses.collection&&element.phones
DEBUG PropertyBinder - Building property phones
DEBUG Ejb3Column - Binding column: Ejb3Column{table=org.hibernate.mapping.Table(Supplier_addresses), mappingColumn=postcode, insertable=true, updatable=true, unique=false}
DEBUG PropertyBinder - binding property postcode with lazy=false
DEBUG SimpleValueBinder - building SimpleValue for postcode
DEBUG SimpleValueBinder - Setting SimpleValue typeName for postcode
DEBUG PropertyBinder - Building property postcode
DEBUG CollectionSecondPass - Mapped collection key: Supplier_id, element: address, city, country, postcode
DEBUG DefaultListableBeanFactory - Retrieved dependent beans for bean 'org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter#102799c': [entityManagerFactory]
INFO  DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@f6ac0b: defining beans [dataSource,entityManagerFactory,testEntities,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor]; root of factory hierarchy
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [test.xml]: Invocation of init method failed; nested exception is java.util.ConcurrentModificationException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1412)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
    at com.primetech.module.purchase.app.TestEntities.main(TestEntities.java:27)
Caused by: java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
    at java.util.AbstractList$Itr.remove(AbstractList.java:357)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1687)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1393)
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1345)
    at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1477)
    at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193)
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1096)
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:685)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:308)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1469)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1409)
    ... 12 more

Removing this part solves the problem

    /**** REMOVE ALL OF THIS FROM THE CODE TO SOLVE THE PROBLEM ****/
    @ElementCollection
    private List<Phone> phones;
    public List<Phone> getPhones() {
        return phones;
    }

    public void setPhones(List<Phone> phones) {
        this.phones = phones;
    }

Please share your thoughts !

Thank you !


JPA 2 spec says no.

JSR-317

2.6 Collections of Embeddable Classes and Basic Types

An embeddable class (including an embeddable class within another embeddable class) that is contained within an element collection must not contain an element collection, nor may it contain a relationship to an entity other than a many-to-one or one-to-one relationship

0

精彩评论

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

关注公众号