我使用EclipseLink 2.5.1进行了以下JPA地图设置
@Entity
@Table(name = "ACCOUNTS")
public class Account extends AbstractAggregateRoot<Long> {
...
private AccountMetadata metadata = new AccountMetadata();
}
@Embeddable
@Access(AccessType.PROPERTY)
public class AccountMetadata extends Metadata {
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name="ACCOUNT_METADATA",
joinColumns=@JoinColumn(table="ACCOUNTS", referencedColumnName="ID", name="ACCOUNT_ID"))
@Column(name= "MD_VALUE")
public Map<Key,String> getMetadata() {
return this.metadata;
}
public void setMetadata(Map<Key,String> md) {
this.metadata = md;
}
}
@Embeddable
public class Metadata implements Serializable {
....
protected Map<Key,String> metadata = new HashMap<>();
@Embeddable
@Access(AccessType.FIELD)
public static class Key {
@Enumerated(EnumType.STRING)
@Column(name = "KEY_NS")
private Namespace ns;
@Column(name = "KEY_NAME")
private String name;
...
}
}
启用缓存后,一切正常。当我通过将以下内容添加到持久性XML
来禁用缓存时<shared-cache-mode>NONE</shared-cache-mode>
尝试提交时收到以下错误。
Caused by: Exception [EclipseLink-69] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: A NullPointerException was thrown while extracting a value from the instance variable [ns] in the object [oracle.cloudstorage.common.domain.Metadata$Key].
Internal Exception: java.lang.NullPointerException
Mapping: org.eclipse.persistence.mappings.DirectToFieldMapping[ns-->KEY_NS]
Descriptor: RelationalDescriptor(oracle.cloudstorage.common.domain.Metadata$Key --> [])
at org.eclipse.persistence.exceptions.DescriptorException.nullPointerWhileGettingValueThruInstanceVariableAccessor(DescriptorException.java:1277)
at org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor.getAttributeValueFromObject(InstanceVariableAttributeAccessor.java:88)
at org.eclipse.persistence.mappings.DatabaseMapping.getAttributeValueFromObject(DatabaseMapping.java:615)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.compareObjects(AbstractDirectMapping.java:407)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.compareForChange(AbstractDirectMapping.java:381)
at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.createObjectChangeSetThroughComparison(DeferredChangeDetectionPolicy.java:186)
at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.createObjectChangeSet(DeferredChangeDetectionPolicy.java:146)
at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChanges(DeferredChangeDetectionPolicy.java:91)
at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChangesForExistingObject(DeferredChangeDetectionPolicy.java:56)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:664)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:438)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:863)
还有其他人遇到过这个问题吗?我尝试了不同的缓存参数,唯一似乎有效的是启用缓存
<shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode>
并将其添加到实体的顶部
@Cache(refreshAlways=true)
答案 0 :(得分:0)
我遇到了同样的问题。看来Eclipselink在使用@ElementCollection
@Embedded
时非常错误。
实现可能依赖于内部缓存来访问这些对象而不是将它们保存在UnitOfWork中,因此如果禁用缓存,您将获得NPE。启用缓存并不能保证您不会获得NPE:在处理大型数据集时也会抛出它。
我提交了2个与此问题相关的BUG: https://bugs.eclipse.org/bugs/show_bug.cgi?id=441498 https://bugs.eclipse.org/bugs/show_bug.cgi?id=442228
目前,解决方法仅对原始成员类型使用@ElementCollections
,并使用@OneToMany
使用地图对象。