这是我的类层次结构(为简洁起见,省略了lombok生成的构造函数/ getters / setter):

public class A
{
    ... other variables ...

    @OneToMany(fetch=FetchType.LAZY, cascade = {CascadeType.ALL})
    private Set<B> bSet = new HashSet<B>();
}

public class B
{
    ... other variables ...

    @CollectionOfElements
    @IndexColumn(name="index")
    private List<C> cList = new ArrayList<C>();
}

public class C
{
    ... other variables ...

    @Embedded
    private D[] dArray;
}

@Embeddable
public class D
{
    ... other variables ...

    private float f1;

    private float f2;
}


问题是,当我保存bSet中包含内容的新A实例时,会收到IllegalArgumentException。这是堆栈跟踪的相关部分:

 org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of path.to.D.f1
    at path.to.dao.commitTransaction(PersistableDAO.java:32)
    at path.to.daoCaller(daoCaller.java:79)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    ... omitted for brevity ...
Caused by: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of path.to.D.f1
    at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:195)
    at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:87)
    at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:93)
    at org.hibernate.tuple.component.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:109)
    at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:376)
    at org.hibernate.type.ComponentType.deepCopy(ComponentType.java:419)
    at org.hibernate.type.ComponentType.deepCopy(ComponentType.java:421)
    at org.hibernate.collection.PersistentList.getSnapshot(PersistentList.java:61)
    at org.hibernate.engine.CollectionEntry.<init>(CollectionEntry.java:91)
    at org.hibernate.engine.StatefulPersistenceContext.addCollection(StatefulPersistenceContext.java:807)
    at org.hibernate.engine.StatefulPersistenceContext.addNewCollection(StatefulPersistenceContext.java:774)
    at org.hibernate.event.def.WrapVisitor.processArrayOrNewCollection(WrapVisitor.java:108)
    at org.hibernate.event.def.WrapVisitor.processCollection(WrapVisitor.java:74)
    at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:124)
    at org.hibernate.event.def.WrapVisitor.processValue(WrapVisitor.java:121)
    at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:78)
    at org.hibernate.event.def.AbstractSaveEventListener.visitCollectionsBeforeSave(AbstractSaveEventListener.java:394)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:296)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
    at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:241)
    at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:292)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:240)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
    at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:320)
    at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:266)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:243)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
    at org.hibernate.engine.Cascade.cascade(Cascade.java:154)
    at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:479)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:357)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
    at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:241)
    at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:292)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:240)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
    at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:320)
    at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:266)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:243)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
    at org.hibernate.engine.Cascade.cascade(Cascade.java:154)
    at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:154)
    at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:145)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:49)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:366)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
    at path.to.dao.commitTransaction(PersistableDAO.java:28)
    ... 52 more
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:169)
    ... 113 more


谁能告诉我发生了什么事?

谢谢!

最佳答案

AFAIK,您不能持久保留Embeddable数组。换句话说,不支持以下内容:

public class C {
    ... other variables ...

    @Embedded
    private D[] dArray;
}


根据JPA 1.0规范:


  2.1.5可嵌入类
  
  实体可以使用其他细粒度
  表示实体状态的类。
  这些类的实例,不同于
  实体实例本身,不
  具有持久的身份。代替,
  它们仅作为嵌入对象存在
  它们所属的实体。这样
  嵌入式对象严格属于
  他们拥有的实体,而不是
  可在持久实体之间共享。
  尝试共享嵌入式对象
  跨实体未定义
  语义。因为这些对象
  没有持久的身份,他们是
  通常与
  他们所访问的实体实例
  属于。
  
  嵌入式类必须遵守
  第2.1节中指定的要求
  对于实体,除了
  未注释可嵌入类
  作为Entity。可嵌入类必须
  被注释为Embeddable
  这样在XML描述符中表示。
  嵌入式对象的访问类型
  由访问类型决定
  嵌入它的实体。
  仅支持一个级别的
  要求嵌入
  规格。
  
  嵌入式要求
  类在本节中介绍
  9.1.34。


JPA 2.0添加了对嵌入式对象集合的支持:


  2.6可嵌入类和基本类型的集合
  
  的持久字段或属性
  实体或可嵌入类可以
  对应于一个基本的集合
  类型或可嵌入的类别(“元素
  采集”)。这样的收藏,当
  由...指定
  ElementCollection注释是
  通过收集表进行映射,
  如第11.1.8节中所定义。如果
  ElementCollection注释(或XML
  没有为
  集合值字段或属性,
  适用第2.8节的规则。
  
  可嵌入的类(包括
  可嵌入类
  包含的可嵌入类)
  在元素集合中一定不能
  包含元素集合,也不得包含
  它包含与实体的关系
  除了多对一或一对一
  关系。可嵌入类
  必须在这样的拥有权
  关系和关系必须
  通过外键映射进行映射。
  (请参阅第2.9节。)


但是我仍然认为您不能映射一系列Embeddable。

09-04 19:44