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.
Related
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.
Breeze supports inheritance as of 1.3.2. The DocTest unit tests demonstrate TPH, TPT, and TPC inheritance, based on an Entity Framework server. I am trying to create a similar data service, with similar type inheritance, e.g BankAccount as a subtype of EntityBase, but using MongoDb in the server instead of EF. So I'm loosely following the Zza sample (except not using Angular.js).
The Zza sample does not use inheritance, and it uses a basic JSON format for its metadata. When I fetched the metadata from the DocTest
http://localhost:45678/breeze/inheritance/Metadata
it appears to be in a different format (JSDL?), so I'm stuck with trying to come up with an equivalent JSON format. Initially this looks like adding "abstract": "true" to my base type in the metadata and "baseType":"EntityBase" to derived types.
Is there any reason to think this won't work without EF? And any reason to prefer TPH (Table Per Hierarchy) over TPC (Table Per Class), for example?
The Breeze client doesn't care if the backend is EF or Mongo, and inheritance is supported for either. What is different between Mongo and EF is that with EF we are able to extract metadata about inheritance relationships from the EF model. This is not possible with Mongo because there is no real metadata about the model stored in the Mongo database. This means that with Mongo you have to create the metadata on the client via Breeze's metadata api. It is completely up to you as to whether and how to create an inheritance structure in the metadata that matches what will be returned from a Mongo query. Take a look at the http://www.breezejs.com/documentation/metadata-by-hand for more information.
I am building an application using Scala 2.10, Salat and Play frmework 2.1-RC2 (will upgrade to 2.1 release soon) and MongoDB.
This is a faceless application where JSON web services are exposed for consumers. Up until now JSON was converted into Model object directly using Play's Json API and implicit converters. I have to refactor some case classes to avoid 22 tuples limit and now instead of flat case class I'm now refactoring to have an embedded case(and embedded MongoDB collection).
Web service interface should remain same where client should still be passing in JSON data as they were before in a flat structure but application needs to map them into proper case class(es) structure. What's the best way to handle this kind of situation. I fear of writing a lot of conversion code <-> Flat JSON <-> complex case class structure <-> from complex case classes to flat JSON output again.
How would you approach such a requirement? I assume case class 22 tuple limit may have had been faced by many others to handle this kind of requirements? How would you approach this
The Play 2.1 json library relies heavily on combinators (path1 and path2). These combinators all have the same 22 restriction. That gives you two options:
Don't use combinators and construct your objects the hard way: path(json) will give you the value at that point in the path. Searching for 'Accessing value of JsPath' at ScalaJsonCombinators will give more examples.
First transform the json into a structure that does not have more than 22 values in a single object and then use the normal combinators. More information about transforming can be found here: ScalaJsonTransformers
I need to store Scala class in Morphia. With annotations it works well unless I try to store collection of _ <: Enumeration
Morphia complains that it does not have serializers for that type, and I am wondering, how to provide one. For now I changed type of collection to Seq[String], and fill it with invoking toString on every item in collection.
That works well, however I'm not sure if that is right way.
This problem is common to several available layers of abstraction on the top of MongoDB. It all come back to a base reason: there is no enum equivalent in json/bson. Salat for example has the same problem.
In fact, MongoDB Java driver does not support enums as you can read in the discussion going on here: https://jira.mongodb.org/browse/JAVA-268 where you can see the problem is still open. Most of the frameworks I have seen to use MongoDB with Java do not implement low-level functionalities such as this one. I think this choice makes a lot of sense because they leave you the choice on how to deal with data structures not handled by the low-level driver, instead of imposing you how to do it.
In general I feel that the absence of support comes not from technical limitation but rather from design choice. For enums, there are multiple way to map them with their pros and their cons, while for other data types is probably simpler. I don't know the MongoDB Java driver in detail, but I guess supporting multiple "modes" would have required some refactoring (maybe that's why they are talking about a new version of serialization?)
These are two strategies I am thinking about:
If you want to index on an enum and minimize space occupation, you will map the enum to an integer ( Not using the ordinal , please can set enum start value in java).
If your concern is queryability on the mongoshell, because your data will be accessed by data scientist, you would rather store the enum using its string value
To conclude, there is nothing wrong in adding an intermediate data structure between your native object and MongoDB. Salat support it through CustomTransformers, on Morphia maybe you would need to do the conversion explicitely. Go for it.
I know, that similar questions are around.
But for my case: I use GWT 2.4 + JPA 2.0 + (MySQL):
Whatis the best data type for my table IDs?
I want to avoid any type conversions in my GWT project.
My desire is easiness, not performance.
Do you advise me to use Wrapper classes i.e long vs. Long?
A simple and straightforward choice is Long. Prefer to use the wrapper class, so you can set the id to null, before the object is inserted into the DB (see also Always use primitive object wrappers for JPA #Id instead of primitive type?)
If performance is not a high priority, you may consider using UUIDs instead: This makes it a lot easier to put objects into sets and maps - before they are stored on the servers side. For easiness, you could use Strings to store the UUIDs (GWT doesn't support the UUID datatype), though using an UUID-specific datatype would be a lot more efficient in a database.
Certainly the wrapper сlass is better than the primitive. Using of object has many advantages. But in my opinion the best choose of type in this situation is class String. Long is undesirable to use in GWT development because JavaScript doesn't have the concept of a long. So recommended to avoid using long if possible. It's emulated on GWT it affects performance.