Java 休眠:初始化与取消固定
我和很多人都有问题Java 休眠:初始化与取消固定,java,hibernate,Java,Hibernate,我和很多人都有问题 @ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) @JoinTable( name = "PORTFOLIO_USER_PERMS", joinColumns = { @JoinColumn(name = "USERNAME") }, inverseJoinColumns = { @JoinColumn(name = "PORTFOLIO_ID"), } ) priva
@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<>();
@ManyToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY)
@可接合(
name=“PORTFOLIO\u USER\u PERMS”,
joinColumns={@JoinColumn(name=“USERNAME”)},
inverseJoinColumns={@JoinColumn(name=“PORTFOLIO_ID”),}
)
私有列表sharedPortfolios=新的ArrayList();
我有一个场景,其中一个sharedPortfolios元素是代理,另一个元素有一个属性是代理(actulay是同一个对象,因为一对一的关系)。此列表通常返回给控制器方法,然后转换为相应的DTO。正如您可能怀疑的那样,带有代理对象的单个属性会导致LazyInitializationException
这意味着在服务中,我需要遍历列表中的每个元素,查找可能是代理的任何属性,并在传递给控制器之前使用Hibernate实用程序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;
}
}
及
或者,您可能希望
在查询中加入FETCH
关系,或者使用实体图,以避免以后必须初始化并避免额外的查询。FETCH=FetchType.EAGER
非常感谢。即使它解决了问题,它也有性能问题。我不需要从数据库中检索那个列表,除非真的有必要。你们如何检索你们的实体?有不同的方法告诉Hibernate急切地获取关系。例如,使用HQL:from Foo Foo join fetch Foo.sharedPortfolios,其中blablabla
实际上我没有使用查询,只是使用sharedPortfolios的getter。管理查询和列表创建的是hibernate。我应该在我的Spring JpaRepository上创建一个方法吗?那么,您是如何获得包含sharedPortfolios
关系的实体的?在那里,你可以“在真正必要的时候”找回这种关系
/**
* 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 );
}
}
}
Hibernate.initialize(entity.sharedPortfolios)