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

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.

Related

what does javax.validation.valid annotation on return type mean?

recently I came across a method declaration in the following format:
#GET
#Path("/foo")
public #NotNull #Valid String foo()
{
...
}
I have problem understanding what the two annotation #NotNull and #Valid mean. Do they have the same effect if they were declared on top of the method declaration like this?
#GET
#Path("/foo")
#NotNull
#Valid
public String foo()
{
...
}
And it seems that if I have the #Valid annotation on, accessing other endpoints in the same class as foo will also trigger the execution of foo().
Could some one share some opinions?
Thanks in advance.
Do they have the same effect if they were declared on top of the method declaration like this?
YES
Accessing other endpoints should not execute foo() unless foo is called somewhere in your code.
#Valid annotation will execute validation on the return value.

JPA Hibernate 5: OneToOne in nested Embeddable causes metamodel issue

I have an entity:
#Entity
public class Test {
#Embedded
Content content;
// getters setters..
}
This contains an embedded class as you can see:
#Embeddable
public class Content {
#OneToOne
Person person;
#Embedded
Language language;
// getters setters..
}
This contains again an embeddable. 2 times nested embeddable
#Embeddable
public class Language {
String format;
#OneToOne
IdentifierCode identifierCode;
// getters setters..
}
When using the automatic schema generation feature of JPA all columns are generated in the correct way.
I use the #Data annotation on each #Entity and #Embeddable to generate getters, setters, constructors, etc..
When starting the application server (EAP 7), I notice this warning in the logs:
HHH015011: Unable to locate static metamodel field :
org.package.Language_#identifierCode; this may or may not indicate a
problem with the static metamodel
Indeed, when opening the metamodel class Language_; no identifierCode column reference is present:
#Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
#StaticMetamodel(Language.class)
public abstract class Language_ {
public static volatile SingularAttribute<Language, String> format;
}
I don't see what I'm doing wroing. Is it not possible to use #OneToOne in a nested #Embeddable? The metamodel Content_ correctly generates the singular attribute for person!
It seems when using multiple nested embeddables, something goes wrong. When using only one level of embeddables, it works.
I tried other stuff:
Adding Access.Field on the class. Nothing happens.
Instantiation the #Embedded class, like #Embedded Language language = new Language(). Nothing happens.
Replaced the #OneToOne with #ManyToOne. Nothing happens.
This sounds like a bug in your JPA provider, which you should report to them.
The JPA provider I use (DataNucleus) creates a
public static volatile SingularAttribute<Language, mydomain.model.IdentifierCode> identifierCode;
One option you have is to just use the datanucleus-jpa-query.jar in your CLASSPATH to generate the static metamodel and use those generated classes with your existing provider, alternatively use it for persistence too.

mapStruct: map list to other list?

I have a list List<Payment> which I'd like to map to another list List<PaymentPlan>. These types look like this:
public class Payment {
#XmlElement(name = "Installment")
#JsonProperty("Installment")
private List<Installment> installments = new ArrayList<>();
#XmlElement(name = "OriginalAmount")
#JsonProperty("OriginalAmount")
private BigDecimal originalAmount;
//getters setters, more attributes
}
and....
public class PaymentPlan {
//(Installment in different package)
private List<Installment> installments;
#XmlElement(name = "OriginalAmount")
#JsonProperty("OriginalAmount")
private BigDecimal originalAmount;
//getters setters, more attributes
}
I expect that something like this is working...
#Mappings({
#Mapping(//other mappings...),
#Mapping(source = "payments", target = "paymentInformation.paymentPlans")
})
ResultResponse originalResponseToResultResponse(OrigResponse originalResponse);
...but I get:
Can't map property java.util.List<Payment> to java.util.List<PaymentPlan>.
Consider to declare/implement a mapping method java.util.List<PaymentPlan> map(java.util.List<Payment> value);
I don't know how to apply this information. First I though I need to declare some extra mapping (in the same mapper class) for the lists, so MapStruct knows how to map each field of the List types like this:
#Mappings({
#Mapping(source = "payment.originalAmount", target = "paymentInformation.paymentPlan.originalAmount")
})
List<PaymentPlan> paymentToPaymentPlan(List<Payment> payment);
...but I get error messages like
The type of parameter "payment" has no property named "originalAmount".
Obviously I do something completely wrong, since it sound like it does not even recognize the types of the List.
How can I basically map from one List to another similar List? Obviously I somehow need to combine different mapping strategies.
btw: I know how to do it with expression mapping, like...
#Mapping(target = "paymentPlans",expression="java(Helper.mapManually(payments))")
but I guess MapStruct can handle this by iself.
I presume you are using version 1.1.0.Final. Your extra mapping is correct, the only difference is that you need to define a mapping without the lists MapStruct will then use that to do the mapping (the example message is a bit misleading for collections).
PaymentPlan paymentToPaymentPlan(Payment payment);
You don't even need the #Mappings as they would be automatically mapped. You might also need to define methods for the Instalment (as they are in different packages).
If you switch to 1.2.0.CR2 then MapStruct can automatically generate the methods for you.

Null pointer when using QueryDSL subtypes

I am trying to create a subtype query along the following lines, but tyre is coming back as null even if I set #QueryInit("tyre") on the wheel property of car.
QWheel wheel = QCar.car.wheel;
QTyre tyre = wheel.as(QRoadWheel.class).tyre;
BooleanExpression tyreFittedOverYearAgo
= tyre.fitted.lt(today.minusYears(1));
Iterable<Car> carsWithOldTyres = repo.findAll(tyreFittedOverYearAgo);
How do I get QueryDSL to initialise tyre when it is accessed using as()?
By default Querydsl initializes only direct reference properties. In cases where longer initialization paths are required, these have to be annotated in the domain types via com.mysema.query.annotations.QueryInit usage. QueryInit is used on properties where deep initializations are needed.
#Entity
class Event {
#QueryInit("customer")
Account account;
}
#Entity
class Account{
Customer customer;
}
#Entity
class Customer{
String name;
String address;
}
This will intialize customer.name ,customer.address
I've not been able to establish why, but I've now got things working but by using:
#QueryInit("*")
Tyre tyre;

Entity Framework: Many-to-Many

I have the following scenario: A Doctor can have multiple Companions. A Companion can also have multiple Doctors. Here are my classses (minus the context):
Public Class Doctor
Public Property DoctorId As Integer
Public Property Regeration As Integer
Public Property Name As String
Public Property Actor As String
Public Property Companions As List(Of Companion)
End Class
Public Class Companion
Public Property CompanionId As Integer
Public Property Name As String
Public Property Actor As String
Public Property Doctors As List(Of Doctor)
End Class
Public Class DoctorViewModel
Public Property DoctorId As Integer
Public Property Actor As String
Public Property Companions As List(Of CompanionViewModel)
End Class
Public Class CompanionViewModel
Public Property Actor As String
End Class
I'm trying to fetch a singular Doctor with a list of companions who have travelled with him. This I can do quite simply, but I'm trying to shape the query to get only a few columns and not the entire entity. He is my bungled query - the X's are what I can't figure out.
Dim query = From d In context.Doctors
From c In context.Companions
Select New DoctorViewModel With {
.Actor = d.Actor,
.DoctorId = d.DoctorId,
.Companions = XXXXXXX}
EDIT: If I query:
(From d In Tardis.Doctors
Where d.Actor = "Tom Baker"
Select New DoctorViewModel With {.Actor = d.Actor, .Companions = d.Companions.Select(Function(c) New CompanionViewModel With {.Actor = c.Actor})}).SingleOrDefault
I get:
"Unable to cast the type 'System.Collections.Generic.IEnumerable1' to
type 'System.Collections.Generic.List1'. LINQ to Entities only
supports casting Entity Data Model primitive types."
Would it be considered nasty to ditch the ViewModel classes in the query and just get the stuff as an anonymous type, then pass this to a constuctor in a ViewModel (my models have a whack of functions that are needed) and fill the class like this?
It probably would be not only okay but much more readable (aka maintainable) as well. Especially since the query wouldn't return an anonymous type, it would return an IQueryable
Solved! I've spent days on this! Trick was to change the List inside the Doctor ViewModel to IEnumerable(Of CompanionViewModel)