How to access a DTO attribute when DTO is inside a hashmap in DOZER mapping file - dozer

I have a UserDTO which has userID field. The HashMap has this DTO as value for key User_Details.
I want to use DOZER mapping to set the userID attribute from HashMap->User_Details->userId to attribute UserDisplayDTO->userId.
How can I do this in Dozer XML mapping?
<mapping map-id="testMapping">
<class-a>java.util.HashMap</class-a>
<class-b>com.common.dto.UserDisplayDTO</class-b>
<field>
<a key="User_Details">this</a>
<b>userId</b>
</field>
</mapping>

You have to define a custom converter for this. Atm, dozer xml mapping doesn't support a keybased hashmap lookup.
So for your case, you need something like
<field custom-converter="com.your.custom.converter.UserIdConverter">
<a>hashmapfield</a>
<b>userId</b>
</field>
In the UserIdConverter implementation, you would have to retrieve the value from the hashmap and return it (null checking etc. omitted for the sake of clarity):
#Override
public Long convertTo(HashMap map, Long userId) {
UserDTO dto = (UserDTO)map.get("User_Details");
return dto.getUserId();
}

Related

Entity Framework navigation with only foreign key

Following the guide lines from Domain Driven Design, I try to avoid having one aggregate referencing a different aggregate. Instead, an aggregate should reference another aggregate using the other aggregate's id, for example:
public class Addiction
{
private Addiction(){} //Needed for EF to populate non-simple types
//DrugType belongs to the aggregate,
//inflate when retrieving the Addiction from the db
//EF does not need DrugId for navigation
Drug Drug{get;set;}
//The supplier is not part of the aggregate,
//aggregates only reference eachother using Ids
int SupplierId{get;set;}
//Other properties
}
public class AddictionConfiguration : IEntityTypeConfiguration<Addiction>
{
builder.HasOne(addiction => addiction.Drug); //Works
builder.HasOne("SupplierId") //Does not work.
}
In this (not very realistic) example, Drug is part of the Addiction's aggregate. When loading this entity from the database using EF, it will also inflate the Drug property without me having to specify the DrugId as the foreign key.
However, now I need to get a list of all Addictions and their suppliers by mapping the relevant properties to a Dto. I try to achieve this by using AutoMapper's ProjectTo functionality, e.g.
_mapper.ProjectTo<AddictionDto>(_dbContext.Addictions.Where(x => x.Id > 1));
where AddictionDto is defined as
public class AddictionDto
{
DrugDto Drug {get;set;}
SupplierDto Supplier {get;set;}
//other properties
}
And
public class SupplierDto
{
public int Id {get;set;}
public string Name {get;set;}
}
Automapper correctly loads the Addiction and also the Drug, but I cannot get it to load the Supplier. I've tried all the options of the IEntityTypeConfiguration to tell EF that there is a navigation property, but I cannot get it to work. Does anyone know if is even possible to do what I described above?

Morphia - Map single collection data into multiple pojos

I have a collection with 40 fields.
I have pojo as follows
#Entity("colName")
public class Entity1 {
//Id
//10 fields - names same as collection columns
#Embedded
//Entity2
}
Entity2 class:
#Embedded
public class Entity2 {
//20 other fields
}
I query the collection as follows
datastore.createQuery(Entity1.class).disableValidation().filter("fieldFromEntity1", "2227536").asList();
But I get always Entity2 reference as null.
I found that Entity2 has to be nested document.
Is there any way to achieve this?
Document:
{
_id: a|b|c,
field1: stringValue,
....
field40: intgerValue
}
Morphia doesn't directly support what you need. However, you can use #Preload and #Presave to manipulate the shapes of documents on their way to/from the database. I think you could also just use, say, Jackson annotations to name/nest those fields when serializing out to json. That'd be the simplest approach.

Mybatis collection with multiple columns

I have a table which has three foreign keys to items. These corresponding objects I want in a list property. I have the following collection mapping
<collection property="items" column="{item1Id, item2Id, item3Id}">
<association property="exampleNestedItem" column="{id, ###itemId###}" select="com.example.mapper.getItem" />
</collection>
I need the current value at ###itemId###. How can I reference the columns "item1Id", "item2Id" and "item3Id" for this Parameter?
I ended up with a very easy solution. In my case I know that there will always be 3 elements in that list. So I added a setter for each element in the model class like this
public void setElement1(Element element) {
elements.add(element);
}
...
and I added an association for each element
<association property="element1" column="element1Id" select="com.example.mapper.getItemWithId"/>
...
It will for sure not scale for many elements, but for my case it fits!

Is it possble to write query at JPA entity property level

Is it possble to write query at JPA entity property level?
Basically I want to add a property in an entity which is not an actual column and value should computed with query.
Something like:
#Entity
#Table(schema = "quote", name = "QUOTE_SCENARIO")
public class QuoteScenario {
#Query(Select max(Lead_Time) from differentEntity)
private Integer leadTime;
}
No. This is not possible as the query annotation is at the method level. You can try and do this using formula in Hibernate.

Dozer - map class field to a flat representation

I've been googling and trying different dozer configuration options but so far couldn't find a simple solution...
Problem is as follow:
class A {
String test;
B test2;
}
class B {
String test3;
String test4;
}
class C {
String test;
String test3;
String test4;
}
Now I would like to map all of the fields from A (including B) to a flat representation in C.
Is it possible to map it using just configuration? The problem is that I need to map B in many different classes and I don't want to write a mapping like this for each of them:
<mapping>
<class-a>A</class-a>
<class-b>C</class-b>
<field>
<a>test2.test3</a>
<b>test3</b>
</field>
<field>
<a>test2.test4</a>
<b>test4</b>
</field>
</mapping>
Would appreciate a solution for that :)
The trick is to use mapping IDs and "this". You need to define caseB only once and can reuse it.
<mapping map-id="caseB">
<class-a>B</class-a>
<class-b>C</class-b>
<field>
<a>test3</a>
<b>test3</b>
</field>
<field>
<a>test4</a>
<b>test4</b>
</field>
</mapping>
<mapping>
<class-a>A</class-a>
<class-b>C</class-b>
<field map-id="caseB">
<a>test2</a>
<b>this</b>
</field>
</mapping>
found on dozer faq :
Can I map one field into another field that is nested n layers deep in the destination object?
Yes. Dozer supports dot notation for nested fields. As with other dozer field mappings, these are bi-directional.
<field>
<a>someNestedObj.someOtherNestedObj.someField</a>
<b>someOtherField</b>
</field>
dozer FAQ