Hibernate Fetch Profiles在JPA 2.0中不起作用

时间:2014-09-25 09:09:45

标签: jpa-2.0 interceptor

我的用例需要加载懒惰的集合。

所以我实现了一些符合我需要的fetchprofiles。

@FetchProfiles(value= {
    @FetchProfile(name=AppUser.EAGER_PROP1_PROP2_PROP3, fetchOverrides= {
            @FetchProfile.FetchOverride(entity=MyEntity.class, association="property1", mode=FetchMode.JOIN),
            @FetchProfile.FetchOverride(entity=MyEntity.class, association="property2", mode=FetchMode.JOIN),
            @FetchProfile.FetchOverride(entity=MyEntity.class, association="property3", mode=FetchMode.JOIN)
    }),
    @FetchProfile(name=AppUser.EAGER_PROP1_PROP2, fetchOverrides= {
            @FetchProfile.FetchOverride(entity=MyEntity.class, association="property1", mode=FetchMode.JOIN),
            @FetchProfile.FetchOverride(entity=MyEntity.class, association="property2", mode=FetchMode.JOIN)
    })
})

为了激活获取配置文件,我写了一个拦截器。此拦截器激活和停用给定的获取配置文件

import java.lang.reflect.Method;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
import javax.persistence.EntityManager;
import org.hibernate.Session;

@Interceptor
public class FetchProfileInterceptor {

    @AroundInvoke
    public Object intercept(InvocationContext ctx) throws Exception {
        Session session = null;
        try {
            session = retrieveSession(ctx);
        } catch (Exception e) {
            throw e;
        }

        Object returnValue;

        if (ctx.getParameters().length > 1) {
            String[] fetchProfiles = (String[]) ctx.getParameters()[1];
            for(String profile : fetchProfiles) {
                session.enableFetchProfile(profile);
            }

            returnValue = ctx.proceed();

            for(String profile : fetchProfiles) {
                session.disableFetchProfile(profile);
            }
        } else {
            throw new Exception("This method has the wrong signature! Need is \"SomeObject obj, String ... fetchProfile\" signature!");
        }
        return returnValue;
    }

    private Session retrieveSession(InvocationContext ctx) throws Exception {
        try {
            Object target = ctx.getTarget();
            Method method = target.getClass().getMethod("getEntityManager");
            EntityManager manager = (EntityManager) method.invoke(target);
            return manager.unwrap(Session.class);
        } catch (Exception e) {
            throw new Exception("Classes that invoke FetchProfileInterceptor must implement the method \"getEntityManager\" with the return type " + EntityManager.class.getCanonicalName());
        }
    }
}

我在EJB中的服务方法:

@Interceptors(FetchProfileInterceptor.class)
public AppUser findByUsername(final String username, String ... overwriteFetchProfile) {
    return repository.findByUsername(username);
}

当我调试代码时,调用拦截器。 fetchprofile已设置但无效。我忘记了什么或做错了吗?

0 个答案:

没有答案