Why Jsr310Converters convert all Jsr310 types only to java.util.Date - jpa

I want to use Java 8 dates in JPA 2.1 entities, but as you know there is no default converters for these types. I have found spring implementation of that converters, but I don't understand implementation.
https://github.com/spring-projects/spring-data-commons/blob/master/src/main/java/org/springframework/data/convert/Jsr310Converters.java
Why spring data Jsr310Converters convert all Jsr310 types to java.util.Date?
Can I map LocalDate to date type field in my database in that case?
**Why conversion java.time.LocalDate <==> java.sql.Date isn't better solution to achieve that goal?
https://github.com/marschall/threeten-jpa
In my opinion this solution is better, but I want to know why spring solution is also good

Related

GORM not serializing java.time types as expected

I'm trying to get some java.time types (LocalDate, ZonedDateTime) to work with Grails 5, GORM 7, with a MongoDb 3.4 database. I'm using the MongoDb plugin v7.3.0, mongodb-driver-core/mongodb-driver-sync v4.5.0.
The appropriate codecs seem to be available from the package org.grails.datastore.bson.codecs, but they don't seem be be getting used. When a document is stored to Mongo, LocalDate and ZonedDateTime are serialized as strings, and when I try to retrieve them, I get this error:
Cannot convert value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'dob': no matching editors or conversion strategy found.
I've reviewed the GORM for MongoDb docs (https://gorm.grails.org/latest/mongodb/manual/), but there isn't much help there. I would assume the appropriate codecs would be automatically registered, but in case the weren't I followed that documentation to register the codecs in my application.yml file, but that didn't work either. Not sure next step on this, maybe I can't do this in Grails?
Edit: Added example repo: https://github.com/MichaelJRussell/mongo-test

Custom operator support in naming convention

as we know, spring-data-jpa supports repositories that generate queries based on function names, i.e (kotlin):
#Repository
interface LocationRepository : JpaRepository<DbLocation, UUID>,
JpaSpecificationExecutor<DbLocation>{
fun findOneByNameIgnoringCase(name: String)
}
Now, postgres supports some custom operators, for example timerange '#>' timestamp (read: timerange contains timestamp).
I'd like to have a function like this, without resorting to native queries/specifications:
#Repository
interface LocationRepository : JpaRepository<DbLocation, UUID>,
JpaSpecificationExecutor<DbLocation>{
fun findOneBySomeFieldContainsTimestamp(something: Instant)
}
Is there any way to extend spring data jpa to also support new operators?
Thanks in advance.
Is there any way to extend Spring Data JPA to also support new operators?
Not really.
Of course, technically the answer is yes since Spring Data is Open Source and you can fork it. A good starting point would be JpaQueryCreator.build() which contains a switch statement for all the supported operators.

Does Spring Data MongoDB support enums?

For Java enum type, I learn that there are two solutions for MongoDB: serialization and using Jackson’s ObjectMapper. Can the MongoRepository work with an enum data type with either of those approaches or I have to write a customized repository?
Yes, Spring Data MongoDB supports enums. Just use them in your domain model.
Spring Data Mongodb can serialize enum into string using enum's name as value. Let's say, it uses the second approach from the article http://www.vineetmanohar.com/2010/01/3-ways-to-serialize-java-enums/. IMHO this can't be taken seriously, because the only correct way to store enums in the database is the approach #3 from the same article, let me cite it: "This approach involves assigning a an explicit user defined value to each enum constant and defining a toValue() and fromValue() methods on the enum to do the serialization and deserialization.". So, Spring Data Mongodb does not support enums.

Automatic Type Conversions in casbah for Bigdecimal

I need to serialize scala.math.BigDecimalvalues using casbah automatic type conversions.
I've imported this
import com.mongodb.casbah.commons.conversions.scala._
and call those methods within the class.
RegisterJodaTimeConversionHelpers()
DeregisterJodaLocalDateTimeConversionHelpers()
But it says, java.lang.IllegalArgumentException: can't serialize class scala.math.BigDecimal.
Isn't casbah support for Bigdecimal serialization or any other way that I can do this?
You would have to write and register your own serializer. BigDecimal is not supported by bson - see the supported types.
The challenge is how to store the type so you can query against it effectively and how best to convert it back on deserialisation (without blanket converting of all types).

Persisting timestamp field as Date or Long?

I need a consensus on the practice of persisting timestamps, specifically on the pros & cons of using java.util.Date compared to using long.
Scope of this discussion:
Performance
Querying Flexibility (e.g. date range)
Any hazards in coding and querying
Portability (e.g. migration to other DB)
About myself:
I consider myself to be a beginner in JPA, dabbling in it once in a while, not being able to apply it into production level projects until now. In my current project, I commit myself to use ObjectDB (embedded) through JPA calls.
The following class demonstrates 3 possible methods for persisting timestamps in JPA:
#Entity
public class Timestamps {
private java.sql.Timestamp ts1;
private #Temporal(TemporalType.TIMESTAMP) java.util.Date ts2;
private long ts3;
:
}
Regarding performance and memory consumption, ts3 is a bit more efficient.
ts3 may be less convenient to use than ts1 and ts2 (in ObjectDB Database Explorer, reports, etc.).
Basic queries such as retrieval by date range are supported for all the three, but extracting date and time parts (YEAR, MONTH, etc.) in queries is not supported for ts3.
All these forms are expected to be portable.
ts1 and ts2 are practically equivalent.
More details are provided in the ObjectDB manual.
In the documentation of java it looks like timestamp is closer related to java.util.date
http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/Timestamp.html
additionally if you care about the semantic of your code, a timestamp is a date.
You should be aware about java.sql.Timestamp's fact before using it:
There are some classes in the Java platform libraries that do extend an instantiable
class and add a value component. For example, java.sql.Timestamp
extends java.util.Date and adds a nanoseconds field. The equals implementation
for Timestamp does violate symmetry and can cause erratic behavior if
Timestamp and Date objects are used in the same collection or are otherwise intermixed.
The Timestamp class has a disclaimer cautioning programmers against
mixing dates and timestamps. While you won’t get into trouble as long as you
keep them separate, there’s nothing to prevent you from mixing them, and the
resulting errors can be hard to debug. This behavior of the Timestamp class was a
mistake and should not be emulated. (Bloch, Effective Java, 2nd Ed.)