Mapstruct: Cannot convert from java.time.LocalDate to java.time.OffsetDateTime - java-time

public class ClassA {
private OffsetDateTime updateBy;
}
public class ClassB {
private LocalDate timestamp;
}
public interface ClassABMapper {
#Mapping(target = "updateBy", source = "classB.timestamp")
ClassA map(ClassB classB);
}
Can't map property "java.time.LocalDate timestamp" to "java.time.OffsetDateTime updateBy". Consider to declare/implement a mapping method: "java.time.OffsetDateTime map(java.time.LocalDate value)".
I tried declaring the following method in mapper.
java.time.LocalDate map(java.time.OffsetDateTime value);
And I am getting error:
error: java.time.LocalDate does not have an accessible empty constructor.
java.time.LocalDate map(java.time.OffsetDateTime value);
Can someone please explain how to perform the conversion?

I created my own custom mapper as explained in the documentation section 5.4. Invoking other mappers. That solved this issue for me.

Related

Any way to reference an attribute of a parameter in the query?

Is there any way to reference an attribute of a parameter that is part of a query for a JPA repository?
My sample is
#Entity
public class Matchday implements Serializable {
#Id
private int matchdayNumber;
//..
//setters and getters defined
//..
//hashCode and equals methods overridden
}
public interface MyRepository extends JpaRepository<Matchday, Integer> {
#Query("... WHERE t.matchday.matchdayNumber < :matchday.matchdayNumber - 1;")
public findByCriteria(Matchday matchday);
}
The construction :matchday.matchdayNumber does not seem to be a valid syntax. Is there any other way to do it than passing the int value for matchdayNumber instead of a reference to Matchday object to this method?
Looks like this is possible with Spring JPA Data which allows SpEL in queries.
public interface MyRepository extends JpaRepository<Matchday, Integer> {
#Query("... WHERE t.matchday.matchdayNumber < :#{#matchday.matchdayNumber - 1}")
public findByCriteria(Matchday matchday);
}

How to list field annotations in Kotlin?

I have an annotation
public #interface Field {
String value();
}
and java class, annotated by it:
public class Animal {
#Field("name")
private String name;
}
I try to list all field' annotations by the next code:
for(field in clazz.declaredFields){
for(annotation in field.annotations){
when(annotation){
is Field -> {
//do something
}
}
}
}
where clazz is Class<T>
but field.annotations is empty.
How to list annotations correctly?
Java annotations, by default, are not retained at runtime so you'll need to specify such:
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
#Retention(RUNTIME)
public #interface Field {
String value();
}
Kotlin annotations are retained by default:
annotation class Field(val value: String)
The issue isn't Kotlin specific, you just haven't configured Field annotation properly. By default, each annotation is retained with RetentionPolicy.CLASS, meaning it won't be accessible via reflection. You have to use RetentionPolicy.RUNTIME if you want to access the annotation in the runtime.
#Retention(RetentionPolicy.RUNTIME)
public #interface Field {
String value();
}

Morphia converter calling other converters

I want to convert Optional<BigDecimal> in morphia. I created BigDecimalConverter, and it works fine. Now I want to create OptionalConverter.
Optional can hold any object type. In my OptionalConverter.encode method I can extract underlying object, and I'd like to pass it to default mongo conversion. So that if there is string, I'll just get string, if there is one of my entities, I'll get encoded entity. How can I do it?
There are two questions:
1. How to call other converters?
2. How to create a converter for a generic class whose type parameters are not statically known?
The first one is possible by creating the MappingMongoConveter and the custom converter together:
#Configuration
public class CustomConfig extends AbstractMongoConfiguration {
#Override
protected String getDatabaseName() {
// ...
}
#Override
#Bean
public Mongo mongo() throws Exception {
// ...
}
#Override
#Bean
public MappingMongoConverter mappingMongoConverter() throws Exception {
MappingMongoConverter mmc = new MappingMongoConverter(
mongoDbFactory(), mongoMappingContext());
mmc.setCustomConversions(new CustomConversions(CustomConverters
.create(mmc)));
return mmc;
}
}
public class FooConverter implements Converter<Foo, DBObject> {
private MappingMongoConverter mmc;
public FooConverter(MappingMongoConverter mmc) {
this.mmc = mmc;
}
public DBObject convert(Foo foo) {
// ...
}
}
public class CustomConverters {
public static List<?> create(MappingMongoConverter mmc) {
List<?> list = new ArrayList<>();
list.add(new FooConverter(mmc));
return list;
}
}
The second one is much more difficult due to type erasure. I've tried to create a converter for Scala's Map but haven't found a way. Unable to get the exact type information for the source Map when writing, or for the target Map when reading.
For very simple cases, e.g. if you don't need to handle all possible parameter types, and there is no ambiguity while reading, it may be possible though.

How to read the new XStreamConverter parameters?

Since version 1.4.2 of XStream, the XStreamConverter annotation takes additional parameters (very good feature and just what I need).
#XStreamConverter(value=CustomXStreamConverter.class, strings={xyz"})
private List<String> phones;
But how can I read this values (xyz) in my custom converter?
public class CustomXStreamConverter implements Converter {
//?
}
I figure out the solution, just override the class constructor in order to receive the parameter.
public class CustomXStreamConverter implements Converter {
private String alias;
public ListToStringXStreamConverter(String alias) {
super();
this.alias = alias; //xyz
}
//...

GWT RPC serializing

I am trying to send over MyClass through RPC, but am getting :
Type MyClass was not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' and did not have a custom field serializer.For security purposes, this type will not be serialized.
I have looked at GWT - occasional com.google.gwt.user.client.rpc.SerializationException and tried their solution, but it did not work.
The difference is that MyClass is located in another project.
The project structure is:
MyApiProject
-contains MyClass
MyClientProject
MyServerProject
I have also tried passing an enum through the RPC from MyApiProject, which also failed.
public class MyClass
implements Serializable
{
private static final long serialVersionUID = 5258129039653904120L;
private String str;
private MyClass()
{
}
public MyClass(String str)
{
this.str = str;
}
public String getString()
{
return this.str;
}
}
in the RemoteService I have:
mypackage.MyClass getMyClass();
in the RemoteServiceAsync I have:
void getMyClass(AsyncCallback<mypackage.MyClass> callback);
I had to change implements Serializable to implements IsSerializable
This usually pops up when you are using another type inside of your class that is not serializable. Check the properties of your class and make sure they are all serializable, post the code of MyClass here and I can look at it as well.
I believe GWT requires an RPC serializable class to also have a public no-argument constructor.
Try removing
private MyClass()
{
}
or set it to
public MyClass()
{
}