当我尝试获取实体属性时遇到奇怪的问题:
Hibernate:
select
tarifklsk0_.ID as ID1_12_0_,
tarifklsk0_.FK_TARIF as FK_TARIF2_12_0_,
tarifservp1_.FK_TARIF as FK_TARIF2_11_1_,
tarifservp1_.ID as ID1_11_1_,
tarifservp1_.ID as ID1_11_2_,
tarifservp1_.FK_TARIF as FK_TARIF2_11_2_,
tarifservp1_.N1 as N3_11_2_
from
TR.TARIFXKLSK tarifklsk0_
left outer join
TR.TARIF_SERV_PROP tarifservp1_
on tarifklsk0_.FK_TARIF=tarifservp1_.FK_TARIF
where
tarifklsk0_.ID=?
Jun 13, 2016 7:38:26 AM org.hibernate.event.internal.DefaultLoadEventListener doOnLoad
INFO: HHH000327: Error performing load command : org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private java.lang.Integer TarifKlsk.fkTarif] by reflection for persistent property [TarifKlsk#fkTarif] : 1027303
Exception in thread "main" org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private java.lang.Integer TarifKlsk.fkTarif] by reflection for persistent property [TarifKlsk#fkTarif] : 1027303
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:43)
....skipped...
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Integer field TarifKlsk.fkTarif to java.lang.Integer
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
我的实体:
关税Klsk
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.BatchSize;
@SuppressWarnings("serial")
@Entity
@Table(name = "TARIFXKLSK", schema="TR")
public class TarifKlsk implements java.io.Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID", updatable = false, nullable = false)
private Integer id;
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name="FK_TARIF", referencedColumnName="FK_TARIF")
@BatchSize(size = 50)
private Set<TarifServProp> tarifservprop = new HashSet<TarifServProp>(0);
@Column(name = "FK_TARIF", updatable = false, nullable = false)
private Integer fkTarif;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set<TarifServProp> getTarifservprop() {
return tarifservprop;
}
public void setTarifservprop(Set<TarifServProp> tarifservprop) {
this.tarifservprop = tarifservprop;
}
public Integer getFkTarif() {
return fkTarif;
}
public void setFkTarif(Integer fkTarif) {
this.fkTarif = fkTarif;
}
}
TarifServProp
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@SuppressWarnings("serial")
@Entity
@Table(name = "TARIF_SERV_PROP", schema="TR")
public class TarifServProp implements java.io.Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID", updatable = false, nullable = false)
private Integer id;
@Column(name = "FK_TARIF", updatable = false, nullable = false)
private Integer fkTarif;
public Integer getId() {
return id;
}
@Column(name = "N1", updatable = false, nullable = false)
private Integer n1;
public void setId(Integer id) {
this.id = id;
}
public Integer getFkTarif() {
return fkTarif;
}
public void setFkTarif(Integer fkTarif) {
this.fkTarif = fkTarif;
}
public Integer getN1() {
return n1;
}
public void setN1(Integer n1) {
this.n1 = n1;
}
}
我的测试模块:
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session sess = sf.openSession();
sess.beginTransaction();
TarifKlsk k2=sess.get(TarifKlsk.class, 1027303);
for (TarifServProp t : k2.getTarifservprop()) {
System.out.println("Tar="+t.getN1());
}
System.out.println("End init");
我做错了什么?我已经检查了这些实体的所有字段,并且所有字段的命名都正确......
更新 我的 POM.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev.hibernate</groupId>
<artifactId>HibernateEHCacheExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<description>Hibernate Secondary Level Cache Example using EHCache implementation</description>
<dependencies>
<!-- Hibernate Core API -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.0.Final</version>
</dependency>
<!-- EHCache Core APIs -->
<!-- http://mvnrepository.com/artifact/net.sf.ehcache/ehcache-core -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.hibernate/hibernate-ehcache -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.2.0.Final</version>
</dependency>
<!-- EHCache uses slf4j for logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>
</dependencies>
</project>
更新2
我发现我的子实体不包含与 master 的 fk_tarif 相对应的 fk_tarif 记录...但我认为没关系,为什么存在错误?
这是5.0和5.1.0版本中的错误 https://hibernate.atlassian.net/browse/HHH-10618
我建议您继续使用 hibernate 版本 4.X.X 而不是版本 5,因为它不是 100% 稳定(更多 2000 个问题)。
https://hibernate.atlassian.net/projects/HHH/issues/HHH-11144?filter=allopenissues
祝你好运
我正在使用 EAP7,其中包含 Hibernate Core {5.0.9.Final-redhat-1}
我有两个实体:
@Entity
@Data
@EqualsAndHashCode(callSuper = true, doNotUseGetters = true)
@ToString(callSuper = true, doNotUseGetters = true)
public class Keuze extends MainTable {
@NonNull
String naam;
@Tolerate
public Keuze() {
}
}
和
@Entity
@Data
@EqualsAndHashCode(callSuper = true, doNotUseGetters = true, exclude = {"gegeven", "werkJaar", "keuze", "keuzes" })
@ToString(callSuper = true, doNotUseGetters = true, exclude = { "gegeven", "werkJaar", "keuze", "keuzes" })
public class Waarde extends MainTable {
@NonNull
@ManyToOne(optional = false, fetch = FetchType.LAZY)
Gegeven gegeven;
@NonNull
@ManyToOne(optional = false, fetch = FetchType.LAZY)
WerkJaar werkJaar;
String alfanumeriek;
Integer numeriek;
BigDecimal valuta;
@Lob
String tekst;
Boolean polair;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
Keuze keuze;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
Set<Keuze> keuzes;
@Tolerate
public Waarde() {
}
}
它们都从这个类扩展而来:
@MappedSuperclass
@Data
@Cacheable
public abstract class MainTable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@Version
Long version;
}
在 Waarde 上调用 merge 时,会抛出以下错误:
Caused by: org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [java.lang.Long vo.cjsm.monitoring.data.schema.dynamic.main.MainTable.id] by reflection for persistent property [vo.cjsm.monitoring.data.schema.dynamic.field.Keuze#id] : Keuze(super=MainTable(id=1, version=0), naam=Leesmotivatie)
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:43)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:223)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4601)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:148)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:850)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:832)
at org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:260)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:398)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:431)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:363)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:111)
at org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:468)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:327)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:170)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:69)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:840)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:822)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:827)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1161)
... 149 more
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Long field vo.cjsm.monitoring.data.schema.dynamic.main.MainTable.id to java.lang.String
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:393)
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:39)
... 171 more
通过删除 Lombok 的 ToString 行并通过覆盖默认的 toString 添加我自己的实现,错误消息消失并且代码恢复正常工作!
现在实体看起来像这样:
@Entity
@Data
@EqualsAndHashCode(callSuper = true, doNotUseGetters = true)
public class Keuze extends MainTable {
@NonNull
String naam;
@Tolerate
public Keuze() {
}
@Override
public String toString() {
return getId().toString();
}
}
因此,不知何故,由于未知原因,toString 方法对 hibernate 合并代码的方式产生了影响...不要问我如何:-) 它似乎起作用了。我尝试了网上的所有其他方法,但没有成功!
希望这对其他人有帮助!
就我而言,问题是在我的模型中,setter 是自动生成的
public void setComments(List comments){
}
没有类型。通过将其设置为
List<Comment> comments
来修复它
从 Hibernate 4 升级到 5 后,我遇到了同样的错误。此时,hibernate bug 似乎在 5.3 之前的任何版本中都没有得到修复。就我而言,这个错误是在延迟获取实体 A 的集合时发生的,该实体 A 与 B 具有热切的一对多关系,使用 A 中的属性,该属性不是主键(我知道,这不是一个好的关系模型)。它实际上可能是一个比这更复杂的边缘情况,但我现在没有时间在最小的测试用例中重现它)。
在跟踪hibernate代码时,似乎hibernate在尝试绑定B查询的参数时感到困惑,并且当它认为尝试获取外键(对象A的属性)时,它实际上已经拥有了适当的价值。该代码将该值视为对象 A,并最终出现如上所示的反射错误。
通过将与 B 的一对多关系更改为惰性关系,我能够克服此错误。我希望这对其他人有帮助。
就我而言,这不是一个错误,而是纯粹的开发人员错误:
@OneToMany(mappedBy = "tableCollection", targetEntity = Diagram.class)
// had to be replaced with
@OneToMany(mappedBy = "tableCollection", targetEntity = Table.class)
我的 targetEntity 错误,因此出现了一个神秘的错误。
也许它可以节省一些时间。
而不是使用:
setParameter("name", variable containing the value);
我通过使用解决了这个问题:
setParameter("name", variable containing the value, StandardBasicTypes.INTEGER);
并导入正确的库:
import org.hibernate.type.StandardBasicTypes;