升级到休眠5

时间:2016-03-29 12:11:28

标签: hibernate jpa

我试图从Wildfly 9更新到10,这也将hibernate从4.3升级到5。

我的查询已经工作了1年多没有问题,但有些问题在升级后会出错。我阅读了迁移指南,但我没有找到可能发生变化的内容,即使它是一个错误。

第一期

第一个问题与我的一个实体中@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)的使用有关。

使用它我开始出现如下错误:

[Server:server-one] Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Short field br.uel.acad.database.cae.model.CalendarioEscolarPK.anoLetivo to br.uel.acad.database.cae.model.CalendarioEscolarPK
[Server:server-one]     at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
[Server:server-one]     at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
[Server:server-one]     at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
[Server:server-one]     at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
[Server:server-one]     at java.lang.reflect.Field.get(Field.java:393)
[Server:server-one]     at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:39)
[Server:server-one]     ... 191 more

由于某种原因,它无法设置我的复合主键的字段。这是我的实体的简化表示:

@Entity
@Table(name = "CALENDARIO_ESCOLAR")
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class CalendarioEscolar implements Serializable {
    @EmbeddedId
    protected CalendarioEscolarPK id;
    //other fields, getters and setters
}

@Embeddable
public class CalendarioEscolarPK implements Serializable {
    @Basic(optional = false)
    @NotNull
    @Column(name = "ANO_LETIVO")
    private Short anoLetivo;
    //other fields, getters and setters
}

搜索方法:

public CalendarioEscolar buscarProximoEventoNaoIniciado(CalendarioEscolar.Evento evento) {
    List<CalendarioEscolar> eventos = em.unwrap(Session.class).createCriteria(CalendarioEscolar.class)
            .add(Restrictions.eq("id.tipEvento", evento.getCodigo()))
            .add(Restrictions.gt("datInicio", new Date()))
            .addOrder(Order.asc("datInicio"))
            .addOrder(Order.asc("id.semestreLetivo"))
            .list();
    if (CollectionUtils.isNotEmpty(eventos)) {
        return eventos.get(0);
    } else {
        return null;
    }
}

如果删除@Cache注释,它会再次起作用。

第二期

第二个问题与加入提取有关。这个简单的查询适用于Hibernate 4.3和habilitacoesAluno属性(oneToMany关系)正确加载:

public DadosAcademicos buscarParaPortalEstudante(Long numMatricula){
    return (DadosAcademicos) em.createQuery("select da from DadosAcademicos da join fetch  da.habilitacoesAluno ha where da.numMatricula = :numMatricula")
            .setParameter("numMatricula", numMatricula)
            .getSingleResult();
}

使用hibernate 5,该属性始终返回null。我发现如果从实体的某个字段中删除fieldHandler,它会再次起作用。

@Entity
@Table(name = "DADOS_ACADEMICOS", schema = "CAE")
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class DadosAcademicos implements Serializable, FieldHandled {
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "dadosAcademicos", fetch = FetchType.LAZY)
    private Set<HabilitacaoAluno> habilitacoesAluno;
    @LazyToOne(LazyToOneOption.NO_PROXY)
    @JoinColumn(name = "NUM_MATRICULA", referencedColumnName = "NUM_MATRICULA", insertable = false, updatable = false)
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private DevedorBiblioteca devedorBiblioteca;
    private FieldHandler fieldHandler;
    public DevedorBiblioteca getDevedorBiblioteca() {
        if (fieldHandler != null) {
            return (DevedorBiblioteca) fieldHandler.readObject(this, "devedorBiblioteca", devedorBiblioteca);
        }
        return devedorBiblioteca;
    }

    public void setDevedorBiblioteca(DevedorBiblioteca devedorBiblioteca) {
        if (fieldHandler != null) {
            this.devedorBiblioteca = (DevedorBiblioteca) fieldHandler.writeObject(this, "devedorBiblioteca", this.devedorBiblioteca, devedorBiblioteca);
        }
        this.devedorBiblioteca = devedorBiblioteca;
    }
    @Override
    public void setFieldHandler(FieldHandler fh) {
        this.fieldHandler = fh;
    }

    @Override
    public FieldHandler getFieldHandler() {
        return fieldHandler;
    }
    //other fields, getters and setters
}

如果我删除fieldHandler,它会再次运行。我知道hibernate 5有一些与字节码检测有关的变化,但我不知道它会发生什么变化。

任何人都知道为什么会出现这些问题?

1 个答案:

答案 0 :(得分:0)

当内存中缓存的大量元素超过值maxElementsInMemory并启用overflowToDisk时,很可能是从Hibernate的二级缓存中读取而导致的错误。我在迁移过程中遇到了同样的问题。

有关详情,请参阅已提出的错误https://hibernate.atlassian.net/browse/HHH-11222