jackrabbit-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Kadir Alaca <al...@web.de>
Subject Re: Programming against interfaces and @Bean-Fields
Date Mon, 14 Sep 2009 14:05:25 GMT
Hi Christophe,

thanks for reply.

Here some additional code with regards,
Kadir


public interface IJcrNodeDAO<T, I extends Serializable> {
    T insert(final T object);
    T find(final String path);
    T update(final T object);
    //...
}


public class JcrNodeDAOImpl<T extends IMyBag, I extends Serializable>
        implements IJcrNodeDAO<T, I> {
    @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<IMyBag, UUID> nodeDaoBag;

    @Autowired(required=true)
    @Qualifier("jcrNodeDaoImage")
    protected IJcrNodeDAO<IMyImage, UUID> 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 <alaca@web.de>:
>   
>> 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.
>>
>>
>>     
>
>   


Mime
View raw message