更新
我想指出@sainr的回答“将Hibernate代理转换为真正的实体对象”确实解决了这个问题。但幕后问题是我的SiteEntity
对setControllerEntity
和getControllerEntity
使用了final
修饰符,这一点我没有在我的问题中提到。我很抱歉。
删除final
修饰符。然后Hibernate就可以很好地初始化代理对象。
关于解释可以在Stack Overflow上的另一个答案中找到。
我有三个如下的实体
@Entity
@Table(name = "controller")
public class ControllerEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(nullable = false, updatable = false)
private long id;
}
@Entity
@Table(name = "site")
public class SiteEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(nullable = false)
private long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "controller_id", nullable = false)
private ControllerEntity controllerEntity;
}
@Entity
@Table(name = "device")
public class DeviceEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(nullable = false)
private long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "site_id", nullable = true)
private SiteEntity siteEntity;
}
在找到设备实体后,我尝试直接从中获取controllerEntity
。
final DeviceEntity deviceEntity1 = deviceRepository.findOne(1L);
System.out.println(deviceEntity1.getSiteEntity().getControllerEntity().getId());
但是,这导致了一个
java.lang.NullPointerException
,它是由于siteEntity
中的null
controllerEntity
引起的。此外,即使我尝试使用
siteRepositoy
重新获取siteEntity
,它的controllerEntity
仍然为null
。当我从DeviceEntity和SiteEntity两个类中都去掉了
fetch=FetchType.LAZY
时,NPE不再发生。但这似乎很奇怪,毫无意义。我能在期望hibernate获取正确值的同时使用
FetchType.LAZY
吗?谢谢。
TransactionTemplate
中使用(或者标记一个方法,在该方法中加载持有者对象并访问延迟加载的子对象时加上@Transactional
)。 - Vladimir SalinSiteEntity
在setControllerEntity
和getControllerEntity
上有一个final
修饰符。移除final
修饰符,然后Hibernate就可以很好地初始化代理对象了。 - Chiu