The main problem seems to be the argument passed to HibernateBeanReplicator.initCollectionPropertyNameSet() being a set of strings instead of CollectionPropertyName instances.
See below for details.
Hanson
1) The code of:
Object replicateObject = new Object();
Doesn't make sense to me. This will just replicate an Object instance. Do you mean to initialize the replicateObject with an instance of a subclass of MySuperClass ?
2) The argument passed to HibernateBeanReplicator.initCollectionPropertyNameSet() is a set of CollectionPropertyName instances, not String instances.
In your case, it should probably be something like:
Set setProperties = new HashSet();
String[] arrayProperties = {"onePropertyNameFromMySuperClass", "otherPropertyNameFromMySuperClass"};
CollectionPropertyName[] tabCollectionPropertyName =
CollectionPropertyName.createCollectionPropertyNames(MySuperClass.class, arrayProperties);
// Note setProperties needs to be a set of CollectionPropertyName instance.
setProperties.addAll(Arrays.asList(tabCollectionPropertyName));
3) Make sure "onePropertyNameFromMySuperClass" and "otherPropertyNameFromMySuperClass" are the actual field names declared in MySuperClass, and that they are subtype of java.util.Collection.
Thanks for your attention, and thanks to you I realize that I was going to a bad direction. First of all, let me answer the three points:
1. I tried to clean my code to show you something a bit more generic ... my bad
2. I don't understand what you mean by a Set because I think that what I made is not wrong (certainly not clean) but I finally send to the initializer a Set of CollectionPropertyName
3. And this point show me the light. I didn't catch the fact that CollectionPropertyName is especially made to specify children of the current object.
So, I think that I need in my case to use a DetailledBeanPopulatable to tell HibernateBeanReplicator which field in each object I want that it replicate.
Thanks again
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi . so when we need to tell HibernateBeanReplicator wich field in each object are replicable we use DetailledBeanPopulatable ? right ? But how? because the interface DetailledBeanPopulatable have only one method shouldPopulate(.....) and it return true o false for one specific property .. so .. it need to be call each time we want to replicate a property .. and what about voters?, it's not an DetailledBeanPopulatable too ?
Please .. don't follow the idea ..
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Sorry for delay, i was on vacations.
And example of my code would be
public class A {
private List<F> af;
...
}
public class F {
private C c;
private List<D> fd;
...
}
public class C {
private List<A> ca ;
private List<D> cd;
...
}
public class D {
private String someField;
...
}
So, what i want to do is to replicate A, but objects F can only replicate c object, not list of D ..
It's an example but thats my question, don't now how to tell to each object if can replicate or not ..
Thanks
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
>So, what i want to do is to replicate A, but objects F can only replicate c object, not list of D ..
I suppose you are asking how this can be done with Hibernate3BeanReplicator. There are multiple ways. Two obvious ones are
1) explicitly/positively specify all the collection member fields you want to replicate; or
2) negatively specify a vetoer
Using your given example, see below for some sample code to do that. Let me know if this works for you.
I be able to test the code presented, but when the object i whant to exclude is a Bean, the readerMethod.getDeclaringClass() return a CGLIB proxy, not the Class it self ..
Be aware that it is not a collection, like the sample you post, is that a problem ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
(Previous post was made on Hibernate's forum : http://forum.hibernate.org/viewtopic.php?t=944303\)
Hi hanson,
This is the way I use the beanLib to do a partial copy of my objects graph. To test your lib, I just ask it to replicate the root object.
[code]
Object replicateObject = new Object();
BeanPopulatable vetoer = new MyVetoer(this.hibernateSessionProvider.getSession());
Set setEntityBean = new HashSet();
Class[] arrayEntityBean = {MySuperClass.class};
setEntityBean.addAll(Arrays.asList(arrayEntityBean));
Set setProperties = new HashSet();
String[] arrayProperties = {"onePropertyNameFromMySuperClass", "otherPropertyNameFromMySuperClass"};
CollectionPropertyName[] tabCollectionPropertyName = CollectionPropertyName.createCollectionPropertyNames(MySuperClass.class, arrayProperties);
setProperties.addAll(Arrays.asList(arrayProperties));
HibernateBeanReplicator replicator = new Hibernate3BeanReplicator()
.initVetoer(vetoer)
.initCollectionPropertyNameSet(setProperties)
.initEntityBeanClassSet(setEntityBean);
replicateObject = replicator.copy(object);
[/code]
This code is wrapped in a method that I made just to test the lib and MyVetoer is basically, the one that you give in the previous post.
Hope this help you to understand what I am trying to do.
Hi Thomas,
The main problem seems to be the argument passed to HibernateBeanReplicator.initCollectionPropertyNameSet() being a set of strings instead of CollectionPropertyName instances.
See below for details.
Hanson
1) The code of:
Object replicateObject = new Object();
Doesn't make sense to me. This will just replicate an Object instance. Do you mean to initialize the replicateObject with an instance of a subclass of MySuperClass ?
2) The argument passed to HibernateBeanReplicator.initCollectionPropertyNameSet() is a set of CollectionPropertyName instances, not String instances.
In your case, it should probably be something like:
Set setProperties = new HashSet();
String[] arrayProperties = {"onePropertyNameFromMySuperClass", "otherPropertyNameFromMySuperClass"};
CollectionPropertyName[] tabCollectionPropertyName =
CollectionPropertyName.createCollectionPropertyNames(MySuperClass.class, arrayProperties);
// Note setProperties needs to be a set of CollectionPropertyName instance.
setProperties.addAll(Arrays.asList(tabCollectionPropertyName));
3) Make sure "onePropertyNameFromMySuperClass" and "otherPropertyNameFromMySuperClass" are the actual field names declared in MySuperClass, and that they are subtype of java.util.Collection.
String[] arrayProperties = {"onePropertyNameFromMySuperClass", "otherPropertyNameFromMySuperClass"};
Thanks for your attention, and thanks to you I realize that I was going to a bad direction. First of all, let me answer the three points:
1. I tried to clean my code to show you something a bit more generic ... my bad
2. I don't understand what you mean by a Set because I think that what I made is not wrong (certainly not clean) but I finally send to the initializer a Set of CollectionPropertyName
3. And this point show me the light. I didn't catch the fact that CollectionPropertyName is especially made to specify children of the current object.
So, I think that I need in my case to use a DetailledBeanPopulatable to tell HibernateBeanReplicator which field in each object I want that it replicate.
Thanks again
Hi . so when we need to tell HibernateBeanReplicator wich field in each object are replicable we use DetailledBeanPopulatable ? right ? But how? because the interface DetailledBeanPopulatable have only one method shouldPopulate(.....) and it return true o false for one specific property .. so .. it need to be call each time we want to replicate a property .. and what about voters?, it's not an DetailledBeanPopulatable too ?
Please .. don't follow the idea ..
If you can put this into some small sample classes and explain what you want to populate and what not, I can show the sample code to achieve that.
Sorry for delay, i was on vacations.
And example of my code would be
public class A {
private List<F> af;
...
}
public class F {
private C c;
private List<D> fd;
...
}
public class C {
private List<A> ca ;
private List<D> cd;
...
}
public class D {
private String someField;
...
}
So, what i want to do is to replicate A, but objects F can only replicate c object, not list of D ..
It's an example but thats my question, don't now how to tell to each object if can replicate or not ..
Thanks
>So, what i want to do is to replicate A, but objects F can only replicate c object, not list of D ..
I suppose you are asking how this can be done with Hibernate3BeanReplicator. There are multiple ways. Two obvious ones are
1) explicitly/positively specify all the collection member fields you want to replicate; or
2) negatively specify a vetoer
Using your given example, see below for some sample code to do that. Let me know if this works for you.
Sample code for (1):
A a1 = ...;
Set<CollectionPropertyName> collectionProperties = new HashSet<CollectionPropertyName>();
collectionProperties.add(new CollectionPropertyName(A.class, "af"));
collectionProperties.add(new CollectionPropertyName(C.class, "ca"));
collectionProperties.add(new CollectionPropertyName(C.class, "cd"));
A a2 = new Hibernate3BeanReplicator().initCollectionPropertyNameSet(collectionProperties)
.copy(a1);
Sample code for (2):
A a1 = ...
A a2 = new Hibernate3BeanReplicator()
.initVetoer(new BeanPopulatable() {
public boolean shouldPopulate(String propertyName, Method readerMethod) {
return readerMethod.getDeclaringClass() != F.class || !propertyName.equals("fd");
}
}).copy(a1);
If, however, you are not using Hibernate, you can also achieve the partial copying with BeanReplicator. Example:
A a1 = ...
A a2 = BeanReplicator.newBeanReplicatable(
BeanTransformer.newBeanTransformer()
.initBeanPopulatable(
new BeanPopulatable() {
public boolean shouldPopulate(String propertyName, Method readerMethod) {
return readerMethod.getDeclaringClass() != F.class || !propertyName.equals("fd");
}
})).replicateBean(a1);
I be able to test the code presented, but when the object i whant to exclude is a Bean, the readerMethod.getDeclaringClass() return a CGLIB proxy, not the Class it self ..
Be aware that it is not a collection, like the sample you post, is that a problem ?
>the readerMethod.getDeclaringClass() return a CGLIB proxy, not the Class it self ..
Try:
UnEnhancer.unenhance(readerMethod.getDeclaringClass())
>Be aware that it is not a collection, like the sample you post, is that a problem ?
CollectionPropertyName can be used for any member field which is either an instance of Collection or Map, if that's what you are concerned about.