Sunday, 15 March 2015

Spring passing CGLIB proxy object to the @Repository layer and Hibernate -



Spring passing CGLIB proxy object to the @Repository layer and Hibernate -

this more conceptual question i.e.

i using spring application context instantiate , manage objects. have application consists of next layers.

model(dao), repository, service

now in repository , service layers classes implement there corresponding interfaces , able phone call method of layer calling method of corresponding interface example:

@autowired public iuserrepository iuserrepository; iuserrepository.dosomething();

in model(dao) layer have classes annotated

@repository @entity @table(name = "users") public class users { ... }

the problem facing flowing. in service layer when seek instantiate object model (dao) layer i.e. :

users usertest = (users)context.getbean("users");

i object of type "users", not "users" object proxy object instantiated trough cglib based proxy. proxy object has additional attributes. see attached image debugging.

when seek pass farther repository layer error listed below

if instantiate object of same class operator "new", works i.e able save object in database.

user = new users(); iuserrepository.createuser(user);

till have learned shell not utilize "new" operator in spring i.e. spring application context(container) shell manage of objects how deal scenario.

my dao users object have default constructor not implement interfaces jdkdynamicaopproxy not beingness used, instead cglib based proxy created. proxy object not accepted user object of repository later i.e. "org.hibernate.mappingexception: unknown entity: " error message.

the question "right" construct/constellation i.e. ok utilize new operator or making typical error not aware of yet.

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 @ org.hibernate.internal.sessionfactoryimpl.getentitypersister(sessionfactoryimpl.java:1095) @ org.hibernate.internal.sessionimpl.getentitypersister(sessionimpl.java:1439) @ org.hibernate.event.internal.abstractsaveeventlistener.savewithgeneratedid(abstractsaveeventlistener.java:116) @ org.hibernate.event.internal.defaultsaveorupdateeventlistener.savewithgeneratedorrequestedid(defaultsaveorupdateeventlistener.java:209) @ org.hibernate.event.internal.defaultsaveeventlistener.savewithgeneratedorrequestedid(defaultsaveeventlistener.java:55) @ org.hibernate.event.internal.defaultsaveorupdateeventlistener.entityistransient(defaultsaveorupdateeventlistener.java:194) @ org.hibernate.event.internal.defaultsaveeventlistener.performsaveorupdate(defaultsaveeventlistener.java:49) @ org.hibernate.event.internal.defaultsaveorupdateeventlistener.onsaveorupdate(defaultsaveorupdateeventlistener.java:90) @ org.hibernate.internal.sessionimpl.firesave(sessionimpl.java:711) @ org.hibernate.internal.sessionimpl.save(sessionimpl.java:703) @ org.hibernate.internal.sessionimpl.save(sessionimpl.java:698) @ org.syncserver.repository.account.userrepositoryimpl.create(userrepositoryimpl.java:186) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62) @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43) @ java.lang.reflect.method.invoke(method.java:483) @ org.springframework.aop.support.aoputils.invokejoinpointusingreflection(aoputils.java:317) @ org.springframework.aop.framework.reflectivemethodinvocation.invokejoinpoint(reflectivemethodinvocation.java:190) @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:157) @ org.springframework.dao.support.persistenceexceptiontranslationinterceptor.invoke(persistenceexceptiontranslationinterceptor.java:136) @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179) @ org.springframework.aop.framework.jdkdynamicaopproxy.invoke(jdkdynamicaopproxy.java:207) @ com.sun.proxy.$proxy76.create(unknown source) @ org.syncserver.service.account.userserviceimpl.create(userserviceimpl.java:266) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62) @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43) @ java.lang.reflect.method.invoke(method.java:483) @ org.springframework.aop.support.aoputils.invokejoinpointusingreflection(aoputils.java:317) @ org.springframework.aop.framework.reflectivemethodinvocation.invokejoinpoint(reflectivemethodinvocation.java:190) @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:157) @ org.springframework.transaction.interceptor.transactioninterceptor$1.proceedwithinvocation(transactioninterceptor.java:98) @ org.springframework.transaction.interceptor.transactionaspectsupport.invokewithintransaction(transactionaspectsupport.java:262) @ org.springframework.transaction.interceptor.transactioninterceptor.invoke(transactioninterceptor.java:95) @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179) @ org.springframework.aop.framework.jdkdynamicaopproxy.invoke(jdkdynamicaopproxy.java:207) @ com.sun.proxy.$proxy81.create(unknown source) @ org.syncserver.core.tests.createuser(tests.java:44) @ org.syncserver.core.application.main(application.java:95)

seem trying create active record mixin straight jpa entities spring-data repositories.

although not acceptable many people, imho approach work improve via composition, ie injecting repositories in entites, not extending them via cglib proxies.

for example:

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) { homecoming repository.findone(id); } @override public void delete() { this.repository.delete(this); } }

note need weaving aspectj, because entities created orm or application code , not spring container.

user user = new user(); user.setname("test"); user.save();

spring spring-aop cglib

No comments:

Post a Comment