gpt4 book ai didi

Spring 将 CGLIB 代理对象传递给@Repository 层和 Hibernate

转载 作者:行者123 更新时间:2023-12-01 15:20:53 24 4
gpt4 key购买 nike

这更像是一个概念性问题,即

我正在使用 Spring Application Context 来实例化和管理我的对象。我有一个由以下几层组成的应用程序。

模型(DAO)、存储库、服务

现在在 Repository 和 Service 层中,所有类都实现了相应的接口(interface),我可以通过调用相应接口(interface)的方法来简单地调用这些层的方法,例如:

@Autowired
public IUserRepository iUserRepository;
iUserRepository.doSomething();

在我的模型(DAO)层中,我有一些用

注释的类
@Repository
@Entity
@Table(name = "USERS")
public class Users {
...
}

我面临的问题是流动性。在我的服务层中,当我尝试从模型 (DAO) 层实例化一个对象时,即:

Users userTest =  (Users)context.getBean("users");

我得到了“用户”类型的对象,但它不完全是“用户”对象,而是一个通过基于 CGLIB 的代理实例化的代理对象。该代理对象具有额外的属性。调试见附图。 enter image description here

当我尝试将它进一步传递到我的存储库层时,出现下面列出的错误

如果我用运算符“new”实例化同一个类的对象,那么一切正常,即我能够将该对象保存在数据库中。

user = new Users();

iUserRepository.createUser(user);

到目前为止,我已经了解到我在 Spring 中不使用"new"运算符,即 Spring 应用程序上下文(容器)shell 管理所有对象,但是如何处理这种情况。

我的 DAO Users 对象确实有一个默认构造函数,但没有实现任何接口(interface),因此没有使用 JdkDynamicAopProxy,而是创建了基于 CGLIB 的代理。但是稍后该代理对象不被接受为我的存储库的用户对象,即我收到“org.hibernate.MappingException:未知实体:”错误消息。

问题是什么是“正确的”构造/星座,即是否可以使用 new 运算符,或者我是否犯了一些我还没有意识到的典型错误。

2014-10-12 11:13:53.707 ERROR 8388 --- [           main] o.s.R.account.UserRepositoryImpl         : Exception

org.hibernate.MappingException: Unknown entity: org.syncServer.Model.acount.Users$$EnhancerBySpringCGLIB$$54139ff4
at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1095)
at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1439)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:116)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:209)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:194)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:711)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:703)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:698)
at org.syncServer.Repository.account.UserRepositoryImpl.create(UserRepositoryImpl.java:186)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy76.create(Unknown Source)
at org.syncServer.Service.account.UserServiceImpl.create(UserServiceImpl.java:266)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy81.create(Unknown Source)
at org.syncServer.core.Tests.createUser(Tests.java:44)
at org.syncServer.core.Application.main(Application.java:95)

最佳答案

看起来你正在尝试创建一个 Active Record通过直接将 JPA 实体与 spring-data Repositories 混合。

虽然许多人不能接受,恕我直言,这种方法通过组合会更好地工作,即在实体中注入(inject)存储库,而不是通过 cglib 代理扩展它们。

例如:

public interface ActiveRecord {
void save();
User load(Long id);
void delete();
}

interface UserRepository extends JpaRepository<User, Long> {

}

@Configurable
class User implements ActiveRecord {
@Id
private Long id;
private String name;
@Transient @Autowired
private UserRepository repository;

@Override
public void save() {
this.repository.save(this);

}
@Override
public User load(Long id) {
return repository.findOne(id);

}
@Override
public void delete() {
this.repository.delete(this);
}
}

请注意,您需要使用 AspectJ 进行编织,因为实体通常是由 ORM 或应用程序代码创建的,而不是由 Spring 容器创建的。

User user = new User();
user.setName("test");
user.save();

关于Spring 将 CGLIB 代理对象传递给@Repository 层和 Hibernate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26324144/

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