Indexed getter only in Dozer - dozer

I'm struggling with a mapping in Dozer. The basic structure of my classes is this:
class Foo {
private String someString;
public String getSomeString() {
return someString;
}
public void setSomeString(String someString) {
this.someString = someString;
}
}
and the interesting part:
class Bar {
// note that no field is declared
public String[0] getSomeBarString() {
// This returns an array where the acctually desired string is a index 0
}
public void setSomeBarString(String someString) {
// stores the string otherwise
}
}
Compensating the absence of a field and the differently named getter/setter methods was quite easy:
<mapping>
<class-a>Foo</class-a>
<class-b>Bar</class-b>
<field>
<a>someString</a>
<b get-method="getSomeBarString" set-method="setSomeBarString">someBarString</b>
</field>
</mapping>
From my understanding I could even omitt get-method and set-method as there is no field access by default.
My problem is that the getter is indexed and the setter isn't. I've already read about indexed property mapping but it does it both ways. Is there a way to make only one direction indexed? E.g. would get-method="getSomeBarString[0]" work?

After a night of sleep I got an idea myself. I just define two one way mappings and make one of them indexed. It also turns out indexing is defined the same way (after the property name) even if you declare a different get-method or set-method.
<mapping type="one-way">
<class-a>Foo</class-a>
<class-b>Bar</class-b>
<field>
<a>someString</a>
<b set-method="setSomeBarString">someBarString</b>
</field>
</mapping>
<mapping type="one-way">
<class-a>Bar</class-a>
<class-b>Foo</class-b>
<field>
<a get-method="getSomeBarString">someBarString[0]</a>
<b>someString</b>
</field>
</mapping>

Related

How to set an attribute of type Collection<> to null in a resultMap?

I have a result map that looks like this:
<resultMap id="myMap" type="myEntity">
<id property="id" column="ID" />
<result property="name" column="NAME" />
<collection property="places" ofType="MyPlace" >
<result property="placeName" column="PLACE_NAME" />
</collection>
<resultMap>
<select id="mySelectStatement" parameterType="MyQuery" resultMap="myMap">
....
</select>
In the incoming parameter (MyQuery) of the select statement I have a flag that indicates whether the places should by joined and resolved or left out. Using the <if test="myFlag" />
construct this all works well.
Now, the only problem that I have is the following: When the flag indicates that the places should be resolved but there are no places connected with the entity then the resulting collection is empty (so far so good). However, when the flag indicates that the places should not be resolved, the resulting collection is also empty.
It is no longer decidable whether the field "places" is empty because there are simply no places or because they weren't being resolved at all. What I would like to have is some mechanism that sets the field "places" to ´null´ instead of returning an empty collection in the case that the flag that decides whether the places should be resolved is set to false.
EDIT:
Some more code to better understand the example
// MyEntity.java
public class MyEntity {
private int id;
private String name;
private List<MyPlace> places;
}
// MyQuery.java
public class MyQuery {
private boolean myFlag;
// getter & setter
}
// MyComponent.java
public class MyComponent {
private MyMapper myMapper;
public void findByQuery(MyQuery myQuery) {
List<MyEntity> myEntities = myMapper.mySelectStatement();
MyEntity firstEntity = myEntities.get(0);
List<Place> places = firstEntity.getPlaces();
if(places.isEmpty()) {
System.out.println("Hm I wonder why they are empty");
}
}
}
// MyMapper.java
public interface MyMapper {
List<MyEntity> mySelectStatement(MyQuery myQuery);
}
// MyMapper.xml
// result map from above
<select id="mySelectStatement" parameterType="MyQuery" resultMap="myMap">
SELECT * FROM MY_ENTITY
<if test="myFlag">
LEFT OUTER JOIN PLACES ON .....
</if>
</select>
And some clarification: This all works in principle. The only problem that I have is that I can not distinguish between an empty collection "places" that is empty because there were no entries in the table AND an empty collection places that is empty because they were not supposed to be resolved in the first place.
My current solution is to check in MyComponent after the method call whether the query that was passed in has the flag set to false. If that is the case, the "places" variable is manually set to null.

Dozer mapping collection

I am new to using dozer. I need to map a collection to a class that is an attribute for the source class in the collect.
I have a class technology as follows
Class Technology {
String name
List<TechnologyOwner> techOwners
}
that I would like to map to
Class TechSummary {
String name
List<Employee> techOwners
}
where
class TechOwner {
Employee techOwner;
Date sinceDt;
}
How will my dozer mapping look like?
Below is the resolve scheme:
1. add mapping configuration in dozerBeanMapping.xml:
<mapping>
<class-a>demo.Technology</class-a>
<class-b>demo.TechSummary</class-b>
<field>
<a>techOwners</a>
<b>techOwners</b>
<b-hint>java.lang.String</b-hint>
</field>
</mapping>
2.use dozer mapper to create destination class:
Mapper mapper = DozerBeanMapperSingletonWrapper.getInstance();
TechSummary techSummary = mapper.map(t,TechSummary.class);
It will be worked.

Dozer mapping of Property of a Object in the list to another list with hints

I have the following scenario of Mapping
Class Contact {
List<SimpleCode> marketSectorList;
}
Class SimpleCode {
protected String code;
protected String label;
}
Class ContactTarget {
List<String> marketSectors;
}
The following map is not working
<mapping>
<class-a>Contact</class-a>
<class-b>ContactTarget</class-b>
<field>
<a>marketSectorList</a>
<b>marketSectors</b>
<b-hint>java.lang.String</b-hint>
</field>
The mapping is not working. Please note that I can not change the classes and I would like to solve by using hints not by custom mappers
You could try to create a mapping from SimpleCode to java.lang.String so dozer knows how to map those objects. Something similar to this:
<mapping>
<class-a>SimpleCode</class-a>
<class-b>java.lang.String</class-b>
<field>
<a>code</a>
<b>this</b>
</field>
</mapping>
I hope it helps.

liferay-6.1 - Implement own service

Hey I have create my own service.xml with student. Now o want to add my own searchByName method for student. can you please explain me what to write in StudentLocalServiceImpl.
public class StudentLocalServiceImpl extends StudentLocalServiceBaseImpl {
/*
* NOTE FOR DEVELOPERS:
*
*/
public List<Student> getAll() throws SystemException {
return studentPersistence.findAll();
}
public Student getStudentByName(String name) {
return studentPersistence.
}
// I have created one method getAll. I need help for the another one.
Thanks in Advance.
You would first declare this as a "finder" element in the service.xml within the entity you defined.
e.g.
<finder name="Name" return-type="Student">
<finder-column name="name" />
</finder>
The return-type could also be Collection if wanting a List<Student> as the return type, if name is not unique.
<finder name="Name" return-type="Collection">
<finder-column name="name" />
</finder>
You can also state a comparison operator for the column:
<finder name="NotName" return-type="Collection">
<finder-column name="name" comparator="!=" />
</finder>
A finder can actually declare a unique index as well to be generated on this relation (will be applied to the DB table) by specifying the unique="true" attribute on the finder:
<finder name="Name" return-type="Student" unique="true">
<finder-column name="name" />
</finder>
With this definition and after re-runing ant build-service the studentPersistence will contain new methods using the name of the finder found in the xml element appended with a prefix: countBy, findBy, fetchBy, removeBy, etc.
Finally, your serice method would only need to contain the following (based on the above):
public Student getStudentByName(String name) throws SystemException {
return studentPersistence.findByName(name);
}
HTH

I need to check for validity of data before deep mapping with dozer, can I?

I'm using dozer to map between my Model Entities and my DTOs.
Now I'm facing with the problem that I need to map some properties of classA.classC to different properties of classB, but first I need to check for inconsistency, because if I don't classC will throws exception and the mapping will not work.
So assume that I have:
class ClassA {
private String name;
private ClassC c;
public ClassC getC() throws ValidityException;
}
class ClassB {
private String code;
private Integer value;
}
class ClassC {
private String name;
private Integer value;
// Getters & Setters below
}
So now I want to map like this:
<mapping>
<class-a>ClassA</class-a>
<class-b>ClassB</class-b>
<field>
<a>c.name</a>
<b>code</b>
</field>
<field>
<a>c.value</a>
<b>value</b>
</field>
</mapping>
if access to ClassC instance from ClassA instance throws exception, I will need to map null for both b properties.
From what I was reading I assume that I should use a CustomConverter in order to access ClassC instance catch the exception and map null in that cases, but not sure how can I implement this kind of converter.
Anyone could give me some ideas about how this can be implemented using Dozer?
Are you sure you wrote the correct mapping? Because ,
<field>
<a>c.name</a>
<b>name</b>
In above snippet, you wrote name for classB. Actually it should be code.