Dozer mapping collection - dozer

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.

Related

How to add two collections inside #Document annotation while developing POJO class?

#Document(collection = "first_collection",collection = "second_collection")
public class Foo {
}
Providing multiple collection names is not supported.This annotation marks a class as being a domain object that we want to persist to the database.
Documentation:
https://docs.spring.io/spring-data/data-mongodb/docs/current/api/org/springframework/data/mongodb/core/mapping/Document.html

OData include "Custom Properties" added to Entity Framework models via Partial Classes

I made a partial class file to add new properties to my Entity-Framework generated model.
I am using WebAPI + OData, and the $metadata doesn't list my new/custom properties, and so the JSON it returns doesn't include my new/custom properties.
For example, let's say my Entity is "Person"
"Person" has one Database property; NumSpouses; an int which is returned in $metadata like this:
<Property Name="NumSpouses" Type="Edm.Int32"/>
That's great, but I added a property like this to a separate file, with a partial class:
public partial class Person {
...
public string MarriedStatus {
get { return this.NumSpouses==0 ? "Single" : "Married"; }
}
...
}
How can I get this Property available in my OData responses?
<Property Name="MarriedStatus" Type="Edm.String"/>
Currently, if I asked for MarriedStatus in $expand (as if it were a NavigationProperty.... which it's not [I thought I'd try $expand anyway as if it magically provided custom properties]), I'd get a message like this:
{
"odata.error":{
"code":"","message":{
"lang":"en-US","value":"The query specified in the URI is not valid. Could not find a property named 'MarriedStatus' on type 'fakeDataModels.Person'."
},"innererror":{
"message":"Could not find a property named 'MarriedStatus' on type 'fakeDataModels.Person'.","type":"Microsoft.Data.OData.ODataException","stacktrace":" at ..."
}
}
}
MarriedStatus is a calculated/readonly property. The ASP.NET implementation of OData does not currently support such properties. As a workaround, add a setter that throws NotImplementedException.
public string MarriedStatus {
get { return this.NumSpouses > 0 ? "Married" : "Single"; }
set { throw new NotImplementedException(); }
}
Optionally, if you are using OData V4, you can annotate MarriedStatus to specify that it is calculated. See Yi Ding's answer to OData read-only property. But the annotation is advisory only; it does not prevent clients from attempting to set a calculated property (e.g., in a POST request).
In addition to the answer of lencharest. You should use the Ignore() function of the Entity Framework fluent API instead of the [NotMapped] attribute. Because OData looks for this attribute to ignore properties for serialization. If you use the fluent API you will not have this problem.
dbModelBuilder.Entity<TEntity>()
.Ignore(i => i.ComputedProperty);

Indexed getter only in 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>

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.

referencing another field in a dozer custom field converter

I have 2 classes with this structure:
class ClassA {
String typeA;
List<String> valuesA;
... other fields go here
}
class ClassB {
String typeB;
List<String> valuesB;
... other fields go here
}
I need to map the valuesA to valuesB and in the custom coverter for this field mapping I need to access the typeA/typeB.
Something like: if typeA is "type1" then map valuesA to valuesB by some algorithm and if typeA is "type2" then map by a different algorithm the valuesA to valuesB.
Is this possible with Dozer?
Thanks!
I think it is possible by using the programmatic (ie in Java) custom converters of Dozer.
See the documentation, especially the TestCustomConverter Java class for an example.