Return-Path: Delivered-To: apmail-jackrabbit-users-archive@minotaur.apache.org Received: (qmail 45529 invoked from network); 17 Sep 2009 13:00:43 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 17 Sep 2009 13:00:43 -0000 Received: (qmail 57854 invoked by uid 500); 17 Sep 2009 13:00:42 -0000 Delivered-To: apmail-jackrabbit-users-archive@jackrabbit.apache.org Received: (qmail 57833 invoked by uid 500); 17 Sep 2009 13:00:42 -0000 Mailing-List: contact users-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@jackrabbit.apache.org Delivered-To: mailing list users@jackrabbit.apache.org Received: (qmail 57822 invoked by uid 99); 17 Sep 2009 13:00:42 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 17 Sep 2009 13:00:42 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: local policy) Received: from [217.72.192.227] (HELO fmmailgate02.web.de) (217.72.192.227) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 17 Sep 2009 13:00:31 +0000 Received: from smtp06.web.de (fmsmtp06.dlan.cinetic.de [172.20.5.172]) by fmmailgate02.web.de (Postfix) with ESMTP id B57DC120DE3EB for ; Thu, 17 Sep 2009 15:00:10 +0200 (CEST) Received: from [82.113.121.24] (helo=[10.46.30.114]) by smtp06.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #314) id 1MoGan-00008r-00 for users@jackrabbit.apache.org; Thu, 17 Sep 2009 15:00:10 +0200 Message-ID: <4AB232D2.5040900@web.de> Date: Thu, 17 Sep 2009 15:00:02 +0200 From: Kadir Alaca User-Agent: Thunderbird 2.0.0.23 (X11/20090817) MIME-Version: 1.0 To: users@jackrabbit.apache.org Subject: Re: Programming against interfaces and @Bean-Fields References: <4AACF0FF.7000308@web.de> <3b728ee90909140603h5a87efbdm36ad571cc20665bd@mail.gmail.com> <4AAE4DA5.3030600@web.de> In-Reply-To: <4AAE4DA5.3030600@web.de> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Sender: alaca@web.de X-Sender: alaca@web.de X-Provags-ID: V01U2FsdGVkX188+LD7V/v3C+xh8H8/il245wPYh75kqwJdQO7v y8N661+uRaMoiySlV6k0H1Ll/I0V89Z4HHBAasz6ILwmdcjBwY Mp6ghn0BI= X-Virus-Checked: Checked by ClamAV on apache.org Hi Folks, since my last post i elaborated a workaround for the issue: proving additional getters and setters only for OCM and move the annotations to the getters. This works, buts its not what i would call clean code! Here a code example: @Node(jcrType="my:imageimpl", extend=MyBagImpl.class, discriminator=false) @Implement(interfaceName=IMyImage.class) public class MyImageImpl extends MyBagImpl implements IMyImage { protected IMyResource image; public IMyResource getImage() { return image; } public void setImage(IMyResource image) { this.image = image; } @Bean(jcrName="my:image", proxy=true, converter=DefaultBeanConverterImpl.class) public MyResourceImpl getImageOCM() { return (MyResourceImpl)image; } public void setImageOCM(MyResourceImpl image) { this.image = (MyResourceImpl)image; } //... } Interfaces are same as before and usage in my domain is only over the interfaces. Is there a neat solution under way? Thanks in advance, Kadir Kadir Alaca schrieb: > Hi Christophe, > > thanks for reply. > > Here some additional code with regards, > Kadir > > > public interface IJcrNodeDAO { > T insert(final T object); > T find(final String path); > T update(final T object); > //... > } > > > public class JcrNodeDAOImpl > implements IJcrNodeDAO { > @Autowired > @Qualifier("jcrMappingTemplate") > protected transient JcrMappingTemplate jcrTemplate; > > public T insert(final T object) { > return (T)jcrTemplate.execute(new JcrMappingCallback() { > public Object doInJcrMapping(ObjectContentManager manager) > throws JcrMappingException { > manager.insert(object); > manager.save(); > return object; > } > }); > } > > public T find(final String path) { > return (T)jcrTemplate.execute(new JcrMappingCallback() { > public Object doInJcrMapping(ObjectContentManager manager) > throws JcrMappingException { > return manager.getObject(path); > } > }); > } > > public T update(final T content) { > return (T) jcrTemplate.execute(new JcrMappingCallback() { > public Object doInJcrMapping(ObjectContentManager manager) > throws JcrMappingException { > try { > manager.checkout(content.getPath()); > manager.update(content); > manager.save(); > manager.checkin(content.getPath()); > } catch (VersionException ex) { > throw new JcrMappingException(ex); > } > return content; > } > }); > } > //... > } > > > @RunWith(SpringJUnit4ClassRunner.class) > @ContextConfiguration(locations = > {"file:web/WEB-INF/config/spring/applicationContext4tests_jcr.xml"}) > @Transactional > public class JcrEventHandlerTest { > @Autowired(required=true) > @Qualifier("jcrNodeDaoBag") > protected IJcrNodeDAO nodeDaoBag; > > @Autowired(required=true) > @Qualifier("jcrNodeDaoImage") > protected IJcrNodeDAO nodeDaoImage; > private String path = "/Kibo_1"; > > //... > @Test > private void test_Insert_Image_Type1() { > IMyImage image1 = > create_a_image_through_some_weird_factory(...); > image1.setPath( path ); > nodeDaoImage.insert(image1); > } > > @Test > private void test_Update_Image_Type1() { > String new_label = "New Label"; > > IMyImage img = nodeDaoImage.find(path); > img.setLabel(new_label); > > nodeDaoImage.update(img); > > IMyImage img2u = nodeDaoImage.find(path); > > assertEquals(new_label, img2u.getLabel()); > } > //... > } > > > > > > Christophe Lombart schrieb: >> Hi Kadir, >> >> Do you have a small unit test. If you have one, it will be easier to >> review your classes. >> I would like to review it maybe it is a bug in the OCM code. >> >> Thanks, >> Christophe >> >> >> 2009/9/13 Kadir Alaca : >> >>> Hi, >>> >>> i have an interface IMyImage and its implementation in MyImageImpl. >>> MyImageImpl has @Bean-Fields which refer to the interface IMyResource. >>> IMyResource is implemented in MyResourceImpl. >>> >>> But here the related code: >>> >>> >>> @Node(isInterface=true, jcrType="my:bag", discriminator=false) >>> public interface IMyBag { >>> //getter and setter defs for path, uuid and other >>> } >>> >>> @Node(isInterface=true, jcrType="my:image", extend=IMyBag.class, >>> discriminator=false) >>> public interface IMyImage extends IMyBag { >>> IMyResource getImage(); >>> void setImage(IMyResource resource); >>> //... >>> } >>> >>> @Node(isInterface=true, jcrType="my:resource", discriminator=false) >>> public interface IMyResource { >>> InputStream getData(); >>> void setData(InputStream data); >>> //... >>> } >>> >>> @Node(jcrType="my:bagimpl", isAbstract=false, discriminator=false) >>> @Implement(interfaceName=IMyBag.class) >>> public class MyBagImpl implements IMyBag { >>> @Field(path = true) >>> private String path; >>> >>> @Field(uuid=true) >>> private String UUID; >>> //... >>> } >>> >>> @Node(jcrType="my:imageimpl", extend=MyBagImpl.class, >>> discriminator=false) >>> @Implement(interfaceName=IMyImage.class) >>> public class MyImageImpl extends MyBagImpl implements IMyImage { >>> @Bean(jcrName="my:image", proxy=true, >>> converter=DefaultBeanConverterImpl.class) >>> protected IMyResource image; >>> >>> public IMyResource getImage() { >>> return image; >>> } >>> >>> public void setImage(IMyResource image) { >>> this.image = image; >>> } >>> //... >>> } >>> >>> @Node(jcrType="my:resourceimpl", isAbstract=false, discriminator=false) >>> @Implement(interfaceName=IMyResource.class) >>> public class MyResourceImpl implements IMyResource { >>> >>> @Field(jcrName="my:binarydata") >>> protected byte[] binarydata; >>> >>> public byte[] getBinarydata() { >>> return binarydata; >>> } >>> >>> public void setBinarydata(byte[] binarystream) { >>> this.binarydata = binarystream; >>> } >>> >>> public InputStream getData() { >>> return new ByteArrayInputStream(this.binarydata); >>> } >>> >>> public void setData(InputStream data) { >>> this.binarydata = FileUtils.toByteArray(data); >>> } >>> //... >>> } >>> >>> >>> >>> >>> >>> When i insert such an image, OCM works pretty fine. >>> Applying an update on that inserted image results to the following >>> exception: >>> >>> Repository access exception; nested exception is >>> org.apache.jackrabbit.ocm.exception.IncorrectPersistentClassException: >>> Class >>> of type: java.lang.Object has no descriptor. >>> org.springmodules.jcr.JcrSystemException: Repository access exception; >>> nested exception is >>> org.apache.jackrabbit.ocm.exception.IncorrectPersistentClassException: >>> Class >>> of type: java.lang.Object has no descriptor. >>> >>> I have debugged OCM and found that >>> >>> public static Class getBeanClass(Object bean) >>> { >>> Class beanClass = bean.getClass(); >>> if (isProxy(beanClass)) >>> { >>> //CGLIB specific >>> return beanClass.getSuperclass(); >>> } >>> return beanClass; >>> } >>> >>> in org.apache.jackrabbit.ocm.reflection.ReflectionUtils returns >>> java.lang.Object >>> for the field >>> protected IMyResource image; >>> >>> The return value is used in ObjectConverterImpl to retrieve the >>> ClassDescriptor for the Bean: >>> ClassDescriptor classDescriptor = >>> mapper.getClassDescriptorByClass(ReflectionUtils.getBeanClass(object)); >>> >>> Of course there is no descriptor for java.lang.Object. >>> >>> When i implement the same structure with concrete classes, OCM works >>> fine. >>> >>> The relevant technology-stack: >>> + jackrabbit 1.6.0 with ocm 1.5.3 >>> + spring 2.5.6 >>> + springmodules 0.9 - with patch from >>> http://jira.springframework.org/browse/MOD-446 >>> + tomcat 6.0.18 >>> + cglib >>> >>> >>> >>> How can i improve my code or maybe OCM self to get done the >>> update-thing >>> with interfaces? >>> >>> Any advice is welcome. >>> >>> Thanks in advance, >>> Kadir. >>> >>> >>> >> >> > >