gpt4 book ai didi

java - hibernate :初始化与取消代理

转载 作者:行者123 更新时间:2023-12-04 17:33:19 24 4
gpt4 key购买 nike

我在使用 ManyToMany 时遇到问题

@ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@JoinTable(
name = "PORTFOLIO_USER_PERMS",
joinColumns = { @JoinColumn(name = "USERNAME") },
inverseJoinColumns = { @JoinColumn(name = "PORTFOLIO_ID"), }
)
private List<Portfolio> sharedPortfolios = new ArrayList<>();

我有一个场景,其中一个 sharedPortfolios 一个元素是代理,另一个元素有一个代理属性(由于一对一关系,actulay 是同一个对象)。此列表通常返回到 Controller 方法,然后将其转换为相应的 DTO。正如您可能怀疑的那样,具有代理对象的单个属性会导致 LazyInitializationException。

enter image description here

这意味着在服务中,我需要遍历列表中的每个元素,在将其传递给 Controller ​​之前,使用 Hibernate Utility:Hibernate.unproxy(...) 查找可能是代理和取消代理的任何属性。

我的问题:

1) Hibernate.initialize 和 Hibernate.unproxy 有什么区别?

初始化代理对象并不能解决问题。

2) 为什么其中一个元素是代理,而其他元素不是?

3)有什么比手动遍历此列表和所有属性并搜索代理对象更好的方法?

太感谢了。

最好的祝福。

最佳答案

要回答您的第一个问题,您可以查看这两种方法的实现:

    /**
* Unproxies a {@link HibernateProxy}. If the proxy is uninitialized, it automatically triggers an initialization.
* In case the supplied object is null or not a proxy, the object will be returned as-is.
*
* @param proxy the {@link HibernateProxy} to be unproxied
* @return the proxy's underlying implementation object, or the supplied object otherwise
*/
public static Object unproxy(Object proxy) {
if ( proxy instanceof HibernateProxy ) {
HibernateProxy hibernateProxy = (HibernateProxy) proxy;
LazyInitializer initializer = hibernateProxy.getHibernateLazyInitializer();
return initializer.getImplementation();
}
else {
return proxy;
}
}
    /**
* Force initialization of a proxy or persistent collection.
* <p/>
* Note: This only ensures initialization of a proxy object or collection;
* it is not guaranteed that the elements INSIDE the collection will be initialized/materialized.
*
* @param proxy a persistable object, proxy, persistent collection or <tt>null</tt>
* @throws HibernateException if we can't initialize the proxy at this time, eg. the <tt>Session</tt> was closed
*/
public static void initialize(Object proxy) throws HibernateException {
if ( proxy == null ) {
return;
}

if ( proxy instanceof HibernateProxy ) {
( (HibernateProxy) proxy ).getHibernateLazyInitializer().initialize();
}
else if ( proxy instanceof PersistentCollection ) {
( (PersistentCollection) proxy ).forceInitialization();
}
else if ( proxy instanceof PersistentAttributeInterceptable ) {
final PersistentAttributeInterceptable interceptable = (PersistentAttributeInterceptable) proxy;
final PersistentAttributeInterceptor interceptor = interceptable.$$_hibernate_getInterceptor();
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
( (EnhancementAsProxyLazinessInterceptor) interceptor ).forceInitialize( proxy, null );
}
}
}
对于实体代理 ( HibernateProxy ) 的实例,这两种方法本质上是相同的,唯一的区别是 unproxy返回未代理的实体。
从我到目前为止的测试来看,无论您使用返回值还是原始引用,都没有区别。 initialize也适用于持久集合 ( PersistentCollection )。当您需要初始化 ToMany-Relation 时,就像在您的问题中一样,您将需要使用此方法。

Initializing the proxy object does not fix the problem.


您需要初始化集合 sharedPortfolios ,不仅仅是包含集合的对象:
Hibernate.initialize(entity.sharedPortfolios)
或者,您可能想要 JOIN FETCH查询中的关系或使用实体图以避免事后初始化并避免额外的查询。

关于java - hibernate :初始化与取消代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57752959/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com