I'm using Joda objects (DateTime and DateTimeZone) in a document and whenever I access it via the REST interface I get entries with fields like this
lastAggregationDate: { content: "2016-07-12T17:58:43.643Z" }
instead of
lastAggregationDate: "2016-07-12T17:58:43.643Z"
I have the Joda Jackson dependencies declared and I see the de/serializers for these types so I'm puzzled as to what's at work here.
I've duplicated this behavior in a slightly modified Spring sample project but using Java's native date types rather than Joda's. I've added a date of birth property to the Person object and modified the shouldRetrieveEntity test to look for $.dateOfBirth.content. I've confirmed the serializer is being used and it seems like the LocalDate object is being treated as a resource rather than as a simple property.
This is fixed in Spring Data Hopper-SR4:
https://jira.spring.io/browse/DATAMONGO-1498
The issue results from Spring Boot not setting up MongoMappingContext correctly. A ticket has been created for Spring Boot and the fix is anticipated for the 1.4.1 release (credit for this answer goes to Oyku Gencay and Oliver Gierke). For more detail, see the ticket or the pull request.
Related
I'm using Spring Batch and Spring Boot and am having a problem when deserializing UUIDs as Jackson reports they are not a trusted class. According to the Spring docs I can add it to the list of trusted classes at construction time:
"Implementation that uses Jackson2 to provide (de)serialization. By default, this implementation trusts a limited set of classes to be deserialized from the execution context. If a class is not trusted by default and is safe to deserialize, you can add it to the base set of trusted classes at construction time or provide an explicit mapping using Jackson annotations"
However there are no examples that I can find. I have tried the following but it doesn't make any difference:
#Bean
ExecutionContextSerializer executionContextSerializer() {
return new Jackson2ExecutionContextStringSerializer("java.util.UUID");
}
Any idea how to do it?
EDIT
I tried Luca Liechti's solution in this post
Spring Batch not deserialising dates
which allowed the deserialization of UUIDs however it caused another issue with converting a List to an ArrayList
For example there are two classes with same name Group in different packages.
But when referring to models in swagger ui only one model is being shown and even the response mapping is not proper, swagger is incorrectly referring to these models.
Yes. Adding the below property solves this issue.
springdoc.use-fqn=true
But after adding this, the schemas in swagger ui start showing up with the complete package name. To avoid this try annotating your model classes with:
#Schema(name = "class name to be displayed")
I meet the same problem today with springdoc-openapi-ui:1.5.9, and maybe solved it.
Simply add key-value pairs to application.properties.
springdoc.use-fqn=true
Then org.springdoc.core.SpringDocConfigProperties read this value, and pass it to io.swagger.v3.core.jackson.TypeNameResolver.
I am doing some debugging on code that throws errors on certain fields during a database query, and some constructor actions of a load method.
We are setting properties manually on an object before creating an instance of a class/model, however for some reason these fields (DateCreated, DateUpdated) are returning null shortly after passing them.
We have validated that these fields are in fact NOT null up until this point, so our concern is that the GORM is deleting and attempting to replace these fields because of naming convention, and perhaps we should leave our own manual setting of these fields out, and allow GORM to manage them.
Is there are way to see which version of GORM the grails app is using, and perhaps get some understanding of how this is managing these fields, and using its own generated constructor for this object?
Depends which version for grails you are using. Assuming you are on newer grails version. The GORM version should be specified in gradle.properties file inside of your grails project and it looks like this:
grailsVersion=3.3.2
gormVersion=6.1.8.RELEASE
gradleWrapperVersion=3.5
You can also find it out from gradle dependency tree with this gradle task:
./gradlew dependencies
We are setting properties manually on an object before creating an
instance of a class/model...
It isn't possible to set properties on an object before creating it.
...so our concern is that the GORM is deleting and attempting to
replace these fields because of naming convention
You haven't said what the property names are but if they are dateCreated and lastUpdated, then GORM will treat those properties specially. If you don't want that, you can turn auto time stamping off, as shown below...
class Person {
Date dateCreated
Date lastUpdated
static mapping = {
autoTimestamp false
}
}
See section 8.1.9 at http://gorm.grails.org/6.1.8/hibernate/manual/index.html#eventsAutoTimestamping.
We currently use a spring/hibernate/jackson backend in our java applications and are considering using ember.js as the frontend. We would like to also use ember-data. The problem is that the JSON format ember-data expects is nothing like what Jackson produces by default.
How can I get Jackson to play nicely with ember-data? Is there a jsonapi.org serializer out there for Jackson?
I just wrote a blog on this very issue. http://springember.blogspot.com.au/2014/08/using-ember-data-restadapter-with.html.
I am using hibernate reverse engineering and trying to get my Timestamps to map to a JodaTime type.
I have setup my hibernate.reveng.xml file properly
<sql-type jdbc-type="TIMESTAMP" hibernate-type="org.joda.time.contrib.hibernate.PersistentDateTime" not-null="true"></sql-type>
The issue is that when i run the rev-eng process my Java classes also get the members created as PersistentDateTime objects, but I don't want that because they are not usable. I need the java objects to be org.joda.time.DateTime
So I tried creating a custom engineering strategy
public class C3CustomRevEngStrategy extends DelegatingReverseEngineeringStrategy {
public C3CustomRevEngStrategy(ReverseEngineeringStrategy res) {
super(res);
}
public String columnToHibernateTypeName(TableIdentifier table, String columnName, int sqlType, int length, int precision, int scale, boolean nullable, boolean generatedIdentifier) {
if(sqlType==Types.TIMESTAMP) {
return "org.joda.time.DateTime";
} else {
return super.columnToHibernateTypeName(table, columnName, sqlType, length, precision, scale, nullable, generatedIdentifier);
}
}
}
My thought was that the hibernate mapping files would get the hibernate.reveng.xml file settings and the java objects would get the settings from the custom strategy file...but that was not the case. Both the mapping file and Object are of type "org.joda.time.DateTime" which is not what I want.
How can I achieve my goal? Also, I am NOT using annotations.
Hibernate 3.6
JodaTime 2.3
JodaTime-Hibernate 1.3
Thanks
EDIT: To clarify exactly what the issue is
After reverse engineering this is what I get in my mapping file and POJO class
<property name="timestamp" type="org.joda.time.contrib.hibernate.PersistentDateTime">
private PersistentDateTime timestamp;
As a POJO property, PersistentDateTime is useless to me as I cannot do anything with it such as time manipulations or anything. So this is what I want after my reverse engineering
<property name="timestamp" type="org.joda.time.contrib.hibernate.PersistentDateTime">
private org.joda.time.DateTime timestamp;
Using the Jidira library as suggested below gives me the same result, a POJO that I cannot use.
The JodaTime-Hibernate library is deprecated, and is probably the source of your problem. Don't dispair however as there is a (better) alternative.
You will need to use the JadiraTypes library to create the correct JodaTime objects from Hibernate. Add the library which can be found here to your project classpath and then change your type to org.jadira.usertype.dateandtime.joda.PersistantDateTime. All of the JodaTime objects have a corresponding mapping in that package, so if you decide to change to another object then just update your type.
This should ensure that your objects get created correctly.
I should add a caveat to my answer, which is that I have never used the JadiraTypes library with Hibernate 3. If it only supports Hibernate 4 (I don't see why it would, but...) let me know and I'll delete my answer.
The Hibernate Tools don't seem to separate Hibernate Types from the Java types. If you would be using annotations, this would be more clear as in that case you'd need an #Type annotation, which Hibernate will not generate at all. So using the exposed APIs won't help here.
Fortunately, Hibernate lets you plug into the actual code (or XML) generation after it does its processing. You can do that by replacing the Freemarker templates it uses to generate both XML and Java code. You'll need to use Ant for reverse engineering, however.
To start using Ant for this purpose (if you're not doing so already), you can either pull Hibernate Tools in as a build-time dependency using your dependency manager or download a JAR. Put the jar in Ant's classpath, but also extract the template files from it: since you're using XML configuration, you'll be interested in the /hbm directory. Then add the task using <taskdef> and, assuming that you extracted the templates to TPL_PATH/hbm/*.ftl, call it using <hibernatetool templatepath="TPL_PATH" ...>. (For more info, see below for a link to the docs). Using Ant also helps with automation, for example on CI servers where you won't have Eclipse.
You'll want to keep hibernate-type="org.joda.time.DateTime" in your hibernate.reveng.xml so that the Java files get generated correctly, but replace it with org.joda.time.contrib.hibernate.PersistentDateTime in the generated XML. To do that, edit TPL_PATH/hbm/property.hbm.ftl, replace ${property.value.typeName} with ${javaType}, and assign javaType to the right value before it's used:
<#assign javaType=property.value.typeName>
<#if javaType.equals("DateTime")>
<#assign javaType="org.jadira.usertype.dateandtime.joda.PersistentDateTime">
</#if>
<property
name="${property.name}"
type="${javaType}"
...
You might want to remove newlines to keep the generated XML clean.
This is all described in the Hibernate Tools documentation at http://docs.jboss.org/tools/archive/3.2.1.GA/en/hibernatetools/html/codegen.html#d0e6349 - except that the documentation doesn't tell you exactly which templates you need to modify, you need to figure that out by reading the templates.