有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java NullPointerException尝试更新包含具有版本字段的透视表的实体

我试图通过一个实体更新数据透视表,该实体作为集合存在,我的数据透视表有一个版本字段,当它更新时抛出一个NullPointerException

我使用Java8和Hibernate作为JPA提供者

主要实体 “a.java”

@JoinColumn(name = "car_subcarpeta_id", referencedColumnName = "sub_id")
    @OneToOne(cascade = CascadeType.ALL)
    @Fetch(FetchMode.JOIN)
    private RjFicha fichaId;

“地毯a.java”的外键 “SubCarpeta.java”

 @OneToMany(mappedBy = "subCarpeta", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @Fetch(FetchMode.SUBSELECT)
    private Collection<item> itemCollection;

数据透视表与子类别相关 “Item.java”

@JoinColumn(name = "i_subcarpeta_id", referencedColumnName = "sub_id")
    @ManyToOne
    private SubCarpeta subCarpeta;

@Column(name = "i_version")
    @Version
    private Integer version;

这是描述NullPointerException源时跟踪的一部分

Caused by: java.lang.NullPointerException
    at org.hibernate.type.IntegerType.next(IntegerType.java:63)
    at org.hibernate.type.IntegerType.next(IntegerType.java:22)
    at org.hibernate.engine.internal.Versioning.increment(Versioning.java:92)
    at org.hibernate.event.internal.DefaultFlushEntityEventListener.getNextVersion(DefaultFlushEntityEventListener.java:383)
    at org.hibernate.event.internal.DefaultFlushEntityEventListener.scheduleUpdate(DefaultFlushEntityEventListener.java:279)
    at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:143)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:216)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:85)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1300)
    at org.jboss.as.jpa.container.AbstractEntityManager.flush(AbstractEntityManager.java:459)
    ... 141 more


共 (2) 个答案

  1. # 1 楼答案

    尝试原语int而不是包装类

    @Column(name = "i_version")
    @Version
    private int version;
    

    整数的默认值为null,int为0

    根据IntegerType API Java文档

    @Override
        public Integer next(Integer current, SharedSessionContractImplementor session) {
            return current + 1;
        }
    

    如果保持整数类null+1,则抛出nullpointerexception

  2. # 2 楼答案

    解决方案将数据库中的表字段设置为NOTNULL,默认值为0

    ALTER TABLE table_name CHANGE COLUMN i_version i_version INT(11) NOT NULL DEFAULT 0;
    

    这是因为,如果字段为NULL,则合并的结果实体将获得版本字段为NULL,并将在稍后抛出NullPointerException

    这是用于更新实体的代码:

    T toReturn = (T)this.em.merge(entity);
    this.em.flush();
    this.em.refresh(toReturn);
    return toReturn;