java - 带有 Map 的 JPA NullPointerException

标签 java jpa eclipselink

我有以下使用 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)

最佳答案

我遇到了同样的问题。在使用 @Embedded@ElementCollection 时,Eclipselink 似乎有很多问题。

可能实现依赖于内部缓存来访问该对象而不是将它们保存在 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 映射对象。

关于java - 带有 Map 的 JPA NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22793445/

相关文章:

java - JPA错误: Transaction is currently active

java - JMX:将 AttributeList 转换为 Map

java - 使用 while 循环根据收到的参数调用方法?

java - Hibernate:根据实体类自动创建/更新数据库表

java - JPA:可以在@OneToMany 上添加额外的 JOIN 约束

java - 可以在 JDBC/MySQL 中检索更新的行吗?

java - 在 JPA 中使用 oneToMany 关系时,Postgresql 在列中抛出空值违反了非空约束

java - 为 Eclipse juno 安装 JPA 插件

用于开发/质量保证/阶段/生产的 JPA 多个持久性单元

java - EclipseLink:级联删除代替更新时出现问题