我试图从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有一些与字节码检测有关的变化,但我不知道它会发生什么变化。
任何人都知道为什么会出现这些问题?
答案 0 :(得分:0)
当内存中缓存的大量元素超过值maxElementsInMemory
并启用overflowToDisk
时,很可能是从Hibernate的二级缓存中读取而导致的错误。我在迁移过程中遇到了同样的问题。
有关详情,请参阅已提出的错误https://hibernate.atlassian.net/browse/HHH-11222