2014-10-12 6 views
2

이 더 개념적인 질문 최대 절전 모드 즉봄 @Repository 계층에 CGLIB 프록시 객체를 전달하고

내가 인스턴스화하고 내 개체를 관리하는 봄 응용 프로그램 컨텍스트를 사용하고 있습니다. 나는 다음과 같은 레이어로 구성된 응용 프로그램이 있습니다.

모델 (DAO), 리포지토리, 서비스

리포지토리 지금

및 서비스 계층 모든 클래스는 단순히 대응하는 인터페이스의 메소드를 호출하여 난 그 층의 메소드를 호출 할 오전 인터페이스 대응이 구현 예를 들어 :

내 모델에서
@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

내가 운영자와 같은 클래스의 객체를 생성하면 내가

아래에 나열된 오류가 내 저장소 계층에 더를 통과하려고 는 "새로운"는 다음 모든 것을 내가 즉 잘 작동 해당 개체를 데이터베이스에 저장할 수 있습니다.

user = new Users(); 

iUserRepository.createUser(user); 

는 지금까지 내가 그러나 방법이 시나리오를 다루는 관리 봄 즉 봄 응용 프로그램 컨텍스트 (컨테이너) 쉘에있는 모든 개체를 "새로운"연산자를 사용하지 쉘을 것을 배웠습니다.

내 DAO 사용자 개체에 기본 생성자가 있지만 인터페이스를 구현하지 않으므로 JdkDynamicAopProxy가 사용되지 않고 대신 CGLIB 기반 프록시가 만들어집니다. 하지만 그 프록시 객체는 나중에 저장소의 User 객체로 받아 들여지지 않습니다. 즉, "org.hibernate.MappingException : Unknown entity :"오류 메시지가 나타납니다.

질문은 "올바른"구성/별자리가 무엇인가입니다. 즉, 새 연산자를 사용하는 것이 좋습니다. 또는 내가 아직 알지 못하는 몇 가지 일반적인 실수를 저지르고 있습니다. 당신이 스프링 데이터 Repositories 직접 JPA 엔티티를 믹스 인에 의해 Active Record을 만들려고처럼

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) 
+0

왜 '사용자'의 새로운 인스턴스를 직접 만들지 않습니까? 'new User()'를 사용하는 데는 아무런 문제가 없습니다. 어쨌든 왜'User'가'@ Repository'입니까? 애플리케이션 (서비스, 리포지토리) 및 인프라 (대기열, 데이터 소스)를 연결하려고하지만 일반적으로 비즈니스 객체는 연결하지 않으려합니다. –

+0

안녕하세요 Deinum, 모델 (DAO) 및 저장소 레이어에 권장 된 것이므로 모델 (DAO)에 대한 "저장소"주석을 선택했습니다. Stackoverflow에서이 권장 사항을 발견했습니다. 나는 그것을 Component로 표시 할 수 있지만 Annotation은 그 클래스의 목적을 반영하지 않는다. 나는 Spring에 새로운 것이기 때문에 정확히 무엇이 옳은 일인지 알지 못했다. 그럼에도 불구하고 Spring은 그 프록시 객체를 Users 객체로 인식하지 못하는 이유가 남아있다. 대신에 최대 절전 모드 예외 인 "org. hibernate.MappingException : 알 수없는 엔티티 : " – Tito

+0

당신은'@ Repository'로 주석을 달아야하는 저장소가 있습니다. 일반적으로 모델은 스프링 관리가 아닙니다 (리치 도메인이나 활성 레코드 또는 기타를 사용하지 않는 한). 당신이 봄이나 디를 사용한다는 사실은 모든 수업을 관리해야한다는 것을 의미하지는 않습니다 ... –

답변

2

이 보인다.

많은 사람들이 받아 들일 수는 없지만, IMHO는 컴포지션을 통해 더 잘 작동합니다 (예 : 엔티티에 리포지토리를 주입하고 cglib 프록시를 통해 확장하지 않음). 예를 들어

: 개체는 일반적으로 ORM 또는 응용 프로그램 코드가 아니라 Spring 컨테이너에 의해 생성되기 때문에 당신이 AspectJ로 직조 필요

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); 
    } 
} 

참고.

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

호세 귀하의 의견을 주셔서 감사합니다 내 코드에서 그 접근 방식을 고려할 것입니다. – Tito