Dozer: class cast exception while mapping lists - java

I have two value objects (ValueObjectA and ValueObjectB), each with name1 and name2
Then I have two lists, each holds one of the value objects, which I plan to map with dozer.
As soon as I access the mapped 'listOfB', I get a Class Cast Exception, since dozer maps objects of type ValueObjectA into the list of ValueObjectsB.
Is it possible to map these two lists without iterating the lists and map object by object?
sample code:
...
// prepare object A
List<ValueObjectA> lostOfA = new LinkedList();
ValueObjectA voA = new ValueObjectA();
voA.setName1("foo");
voA.setName2("bar");
lostOfA.add(voA);
// map object A to object B
List<ValueObjectB> listOfB = new LinkedList();
mapper.map(lostOfA, listOfB);
for (ValueObjectB voB:listOfB ){
...

Not easily.
Take a look at this thread on the Dozer forum.
To quote:
"Nested collections are handled
automatically, but you are correct
that top level collections need to be
iterated over. Currently there isn't a
more elegant way to handle this."

Try to define a mapping for both class . Dozer will use this mapping at run-time automatically and convert objects accordingly.
for example (psudo code) :
<mapping>
<classA>ValueObjectA</classA>
<classB>ValueObjectB</classB>
<mapping>
I guess the fields name in both class are same. If not you need to specify them in the above mapping.

Related

safe json to java serialization/deserialization

I would like to know how you would do this :
I have a java data object. This object contains object attributes that contains object attributes...
I serialize my objects using json-io. But when deserializing, I want to protect the data if an object fails to deserialize. So I got the idea to json-serialize each attribute before serializing any object. This way, if an attribute fails to deserialize, the object itself is safe.
this means that if I have an object {a:v1,b:{ba:v2,bb:{bba:v3,bbb:v4}}}, I will serialize it like this instead : "{\"a\":\"v1\",\"b\":\"{\\\"ba\\\":\\\"v2\\\",\\\"bb\\\":\\\"{\\\\\\\"bba\\\\\\\":\\\\\\\"v3\\\\\\\",\\\\\\\"bbb\\\\\\\":\\\\\\\"v4\\\\\\\"}\\\"}\"}"
You see that on a very simple object it becomes very uneasy to read. Imagine with a more complex one !
I would like to do something about it, but I found no good ideas. Maybe the best would be when I read/write the json to call a function able to remove/re-add the "\" where they are needed, but I don't succeed to find the correct algorithm... Any hint ? Or maybe another method ?
Thanks a lot !
Ok. My approach was wrong. I created a Data object like a Map that contains Data or String. Then, I can safely deserialize Data elements. It means that this time I have a tree, where all the trunk is a safe Data object, and only the leafs are json-serialized generic objects.
public class Data implements Serializable {
private final Map<String, Data> node = new HashMap<>();//safe tree object
private final Map<String, String> leafs = new HashMap<>();//unsafe serialized object
}
In my previous example, the result would be :
//initial object
{a:v1,b:{ba:v2,bb:{bba:v3,bbb:v4}}}
//becomes
{"a":"{v1}","b":{"ba":"{v2}","bb":{"bba":"{v3}","bbb":"{v4}"}}}
And the \ would appear only if one of the unsafe values contains a String.
Thanks a lot Ryan, Talking to you helped me a lot to better define the problems, which is always the first step to the solution.

Is a HashMap a proper data structure

I store in a HashMap 3 types of object.
HashMap<String, ArrayList<Car>>
['Lorry', [list of lorries]]
['Sport', [list of sport's cars]]
The HashMap string key keeps the type of object (a subclass of Car), the second element stores in array the objects that have e.g. attributes like: ID, date etc.
The four main things I have to do are:
Check if certain ID exist in HashMap when there is no information provided about its type
Print elements of certain ID given the type.
Print all elements of certain type
Print all element from the collection (of different types) if certain attribute that each object has assigned has a Boolean value of e.g. "true";
Is the HashMap the proper structure? I find it problematic if it comes to the first point. It seems like I will have to traverse the whole collection and if so what other collection is better for such requirements?
The basic approach is sound, however since you only want to store each instance once, a Set is a better choice than a List for the map entry value:
Map<String, Set<Car>> typeCache = new HashMap<String, HashSet<Car>>();
The contains() method of HashSet is very fast indeed, so finding if your map contains a particular instance in it values is not going to cost much.
Using two maps would probably be better though - once for each type of lookup, so also use:
Map<String, Object> idCache = new HashMap<String, Object>();
A HashMap is the right data structure for the job, but in your case you might consider using two HashMaps: One holding the relation 'Car Type' -> 'Cars of that Type', and a second one for the relation 'ID' -> 'Car with that ID'.

Help need with transforming Java lists/collections or something

I have a list of objects returned from getJdbcTemplate().query
that look like this
object(test,test,test,1)
object(test,test,test,2)
object(test,test,test,3)
How can I transpose these into one object that looks like this
object(test,test,test,list<t>({1,2,3}))
Hopefuly you get the idea from my ropey psuedo object representation :)
I think using RowMapper can be a little painful. Perhaps, you can do something like this (by the way, this is my pseudo):-
List<Map> rows = getJdbcTemplate().queryForList(sql);
MyObject obj = null;
for (Map row : rows) {
// configure the first 3 fields upon object creation.
if (obj == null) {
obj = new MyObject(row.get("firstField"), row.get("secondField"), row.get("thirdField"));
}
// basically add each item into the list
obj.addToList(row.get("fourthField"));
}
JdbcTemplate deals with rows, so you need a RowMapper to extract the values and convert them into a List of a custom type (implement a class that corresponds to this structure object(test,test,test,1)). Then you can work on the extracted values and assemble your new object from the list values.
Reference:
Examples of JdbcTemplate class
usage
JdbcTemplate javadoc
RowMapper<T> javadoc
Couldn't you use a 2 dimensional array?
http://www.willamette.edu/~gorr/classes/cs231/lectures/chapter9/arrays2d.htm
I'm kind of a noob at java so if I'm not correct, please excuse my ignorance.
Extend your Object Model.
You need to create a new object, similar to the one you are creating with the individual value argument, which instead takes a list or a collection as the final argument. Instead of storing a single value there, your object will store a list or a collection there. If this list or collection will be immutable once the object has been created, you should consider converting the data to an int[] before storing it.
Then, build whatever methods you need on this new object. You can even write a method to return an array of the old objects, where each object has only one value in it.

Bind objects in a Set collection

I have a form which fills some objects of a Collection. I had the collection implemented with a List (an everything worked good), but now I want to use a Set. I have a property editor registered to create the objects. The problem is that I don't know what is the syntax I must use to populate the objects of the Set.
public class MyObject(){
Set<OtherObject> otherObjects = new HashSet();
}
I have tried with the syntax in the form tags, like the syntax a list:
name="otherObjects['${status.index}']"
and like the syntax for a map:
name="otherObjects['${id}']"
but both come to an error because "Property referenced in indexed property path 'otherObjects[0]' is neither an array nor a List nor a Map"
I have also tried with
name="otherObjects"
but this doesn't fill the objects.
Can anyone tell me how to bind the data to the objects in a Set.
Thanks
According to the documentation on data binding, you can only user the bracket notation to bind to nested objects in a "naturally ordered collection". A set doesn't qualify.
Can't you use the old syntax in the form tags and add a getter that will return a set of objects?
public class MyObject(){
List<OtherObject> otherObjectsList = new ArrayList<OtherObjects>();
public Set<OtherObject> getOtherObject()
{
return new HashSet<OtherObject>(otherObjectsList);
}
}

Avoiding duplicate objects in Java deserialization

I have two lists (list1 and list2) containing references to some objects, where some of the list entries may point to the same object. Then, for various reasons, I am serializing these lists to two separate files. Finally, when I deserialize the lists, I would like to ensure that I am not re-creating more objects than needed. In other words, it should still be possible for some entry of List1 to point to the same object as some entry in List2.
MyObject obj = new MyObject();
List<MyObject> list1 = new ArrayList<MyObject>();
List<MyObject> list2 = new ArrayList<MyObject>();
list1.add(obj);
list2.add(obj);
// serialize to file1.ser
ObjectOutputStream oos = new ObjectOutputStream(...);
oos.writeObject(list1);
oos.close();
// serialize to file2.ser
oos = new ObjectOutputStream(...);
oos.writeObject(list2);
oos.close();
I think that sections 3.4 and A.2 of the spec say that deserialization strictly results in the creation of new objects, but I'm not sure. If so, some possible solutions might involve:
Implementing equals() and hashCode() and checking references manually.
Creating a "container class" to hold everything and then serializing the container class.
Is there an easy way to ensure that objects are not duplicated upon deserialization?
Thanks.
After deserialization of the second list you could iterate over it's the elements and replace duplicates by a reference to the first list.
According to 3.7 The readResolve Method the readResolve() method is not invoked on the object until the object is fully constructed.
I think that sections 3.4 and A.2 of the spec say that deserialization strictly results in the creation of new objects, but I'm not sure. If so, some possible solutions might involve: ...
2, Creating a "container class" to hold everything and then serializing the container class.
I read these statements as "if I my understanding about deserialization always creating new objects is incorrect, then solution #2 of writing both lists wrapped in a container class to a single stream is an acceptable solution."
If I am understanding you correctly, this means you think writing out through a single container containing both lists won't work because it will still result in duplicate objects ("strictly results in ... new objects"). This is incorrect. When writing out the graph of objects (your wrapper class), each object is only serialized once, no matter how many occurrences in the graph. When the graph is read back in, that object is not duplicated.
http://java.sun.com/javase/6/docs/api/java/io/ObjectOutputStream.html
The default serialization mechanism for an object writes the class of the object, the class signature, and the values of all non-transient and non-static fields. References to other objects (except in transient or static fields) cause those objects to be written also. Multiple references to a single object are encoded using a reference sharing mechanism so that graphs of objects can be restored to the same shape as when the original was written.
So, if you can, use option #2.
Creating a "container class" to hold everything and then serializing the container class.
You can override the readResolve() method to replace what's read from the stream with anything you want.
private Object readResolve() throws ObjectStreamException {
...
}
This is typically used for enforcing singletons. Prior to Java 5 it was also used for typesafe enums. I've never seen it used for this but scenario but I guess there's no reason it couldn't be.
Now this will work with individual objects that you control but I can't see how you'd make it with a List. It could ensure that the objects returned in that list aren't duplicated (by whatever criteria you deem).

Categories