我正在尝试使用延迟加载我的实体来实现Repository模式(我不能使用JPA,因为它是一个遗留数据库模型)。为了延迟加载实体,我使用cglib MethodInterceptor来拦截实体的getter方法,并动态地水合相应的属性。例如,在Airport实体的情况下,只有在调用相应的getter时,我才会延迟加载Terminals属性。整件事打包为弹簧启动应用程序。
存储库实现由:
给出@Component
public class AirportsRepository implements Repository<Airport, String> {
@Autowired
private AirportMapper airportMapper;
@Autowired
private TerminalMapper terminalMapper;
private List<AirportInterceptor> airportInterceptors = new ArrayList<>();
@Override
public Airport get(String id) {
Airport airport = airportMapper.findById(id);
if(airport != null){
AirportInterceptor airportInterceptor = new AirportInterceptor(airport, terminalMapper);
airport = (Airport) Enhancer.create(Airport.class,airportInterceptor);
this.airportInterceptors.add(airportInterceptor);
return airport;
}
return airport;
}
@Override
public void add(Airport entity) {
//
}
@Override
public void remove(Airport entity) {
//
}
@Override
public void saveChanges(){
//
}
}
public class Airport
{
// ...
}
方法拦截器:
class AirportInterceptor implements MethodInterceptor {
private TerminalMapper terminalMapper;
private Airport airport;
public AirportInterceptor(Airport airport, TerminalMapper terminalMapper){
this.airport = airport;
this.terminalMapper = terminalMapper;
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
if(method.getName().equals("getTerminals") && method.invoke(obj, args) == null){
// Hydrate terminals
List<Terminal> terminals = terminalMapper.findByAirportCode(airport.getId());
airport.setTerminals(terminals);
}
return method.invoke(obj, args);
}
public void saveChanges(){
//airportMapper.update(this.airport);
}
}
但是,当我调用Enhancer.create()时,我遇到了存储库代码的问题,这会引发关于方法toString()的神秘异常:
Method threw 'java.lang.reflect.InvocationTargetException' exception. Cannot evaluate com.apm.airportservice.entities.Airport$$EnhancerByCGLIB$$d0daae41.toString()
答案 0 :(得分:0)
如何配置Enhancer
类?
您可能需要在班级添加此注释:
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)