Save class field in particular order in Spring couchbase - spring

I am using couchbase as Spring-data in Spring boot application,
I am saving a class let say Employee
which contain fields empId, empName, empDesc etc.
I wanted to save this object in couchbase in particular order.
Lets say I wanted to save this json in couchbase in the order
{
"empName": "hello",
"empDesc": "helloDesc",
"empId": "hello11"
}
How can I can acheive this?
Any help is appreciated.

I think you miss the point. Order of keys is irrelevant in a JSON object, be it in Couchbase or not.
An object is an unordered set of name/value pairs.
Cf http://json.org/
If the order is so important to you, you should use a JSON Array.
Don't use an API or framework in a devious way, it usually ends bad.

Related

How do I map "id" property into "id" field in Mongo without #Field annotation?

I have multiple classes with the id field. I would like to store their instances in MongoDB using spring-data-mongodb. I would like to map id property in these classes to id field in Mongo.
So here is what my classes look like:
public class Entity {
private final String id; // = 42
...
}
And here is what I am expecting to be in Mongo collection:
{
"_id": ObjectId("5fba805dfdaaa760974d45de"),
"id": "42"
}
By default, spring-mongodb maps id property to _id field in Mongo. I know that the simplest way to avoid this is to put #org.springframework.data.mongodb.core.mapping.Field("id") annotation on id property in a Java class. But I prefer not to use this annotation since I would like to keep my model independent of Mongo, or Spring, or whatever. Which options are possible here?
Here is what I have tried or checked:
Registering custom AbstractMongoEventListener in order to modify Mongo documents just before they are written to Mongo, or just after they have been read from Mongo. It does not work for me since custom listener is called only during get and insert operations, but not during the update or upsert operations (see discussion here for details).
Providing custom FieldNamingStrategy — it does not work since in the spring-data-mongodb code they use strategy only if field name is not id or _id.
Providing custom converter for each of my classes. I believe it should work. But this approach seems to be too complicated since I have many classes with many properties in each of them and I'm not sure I would like to have many converters with boilerplate code inside.
Any help would be appreciated.
Don't you think that id with _id is already confusing?
If you have a strong valid reason to have an id (different than DB one); give it a name .e.g: version_id, old_id, other_services_id ... some meaningful name.
And yes using #Field in your case is the simplest way

Spring data JPA to filter by multiple fields and return projections

I am working on a PoC of a simple RESP API with a MySQL database. I am using Spring Data JPA and Spring Web. I think my my use case is very common and yet I haven't found the best solution. Here is the details.
For the sake of the discussion, let's use an entity Person with say 50 different fields/columns (e.g. id, name, age, etc.)
I want to expose a simple HTTP GET endpoint that would return a JSON with a list of people. I want to offer the user the following request params:
withName to filter by name.
withAge to filter by age.
... some other withXXX, although not as many as the number of fields. Let's say 5 more.
sortBy to sort
page and pageSize to paginate.
fields to decide what fields the user wants to get in the response
An example of a possible call would be:
GET /people?withName=Charly&withAge=30&withCountry=esp&sortBy=name&page=1&pageSize=10&fields=id,surname,genre
[
{
"id": 1,
"surname": "Smith",
"genre": "male"
},
{
"id": 45,
"surname": "Doe",
"genre": "female"
},
...
]
Now, after having read here and there, I think it would be good to have the following:
Use DTO (Spring projections) because I don't want to get the 50 columns from the database if it's not required (see fields request param).
Use perhaps specifications because the fields to filter with are chosen by the user in the request.
Use standard sorting and pagination features offered by JPA/Spring data.
I was expecting this use case to be very common, but I am surprised that I haven't found it anywhere else. This makes me think that I am doing something wrong.
Do I need to implement this "manually" using queries or criteria? I expect to have a high number of entities and was expecting not to have to implement this for every one of them.
I saw this interesting article, but it isn't using projections, which I think it's important.
I also have read articles in Baeldung, in Vlad Mihalcea's site, in Thorben Janssen's site and, of course, Stack Overflow, all related to the use of DTO, projections, etc., but again, I haven't found anywhere an example mixing Spring data, projections with a dynamic number of fields, filtering using multiple fields and pagination.
I am started to think that I am asking too much, but I see this scenario and think that people must have faced it many times in the past.
Can anybody help, please. Thank you very much.

Spring JPA data not inserting into the order in which it posted

I don't know wheather anyone had this type of issue before or not! So but basically when i do save object it insert random order but not actual order in which i am sending it from POST api via UI. Below is my json object which i am sending to spring jpa for insertion,
{"expense":"wwww","amounts":[{"amount":"23","version":0},{"amount":"12","version":0},{"amount":"27","version":0},{"amount":"22","version":0},{"amount":"22","version":0},{"amount":"1111","version":0}],"version":0}
and this amounts are the Set<expense> amounts into my parent object as #manytomany relationship. And data insert into the random order but it should have insert the order which it sent from, correct me if i am wrong anywhere. In database it saves like 22,12,22,1111,,23,27 which is random.
In Java the Set interface doesn't guarantee any order. You can use a SortedSet for your mapping, or use a List. Both can be ordered and will preserve the one received from some JSON.
Some documentation :
Set Javadoc
SortedSet Javadoc

Spring Data- how to tell spring what entities to retrieve

If i have several entites, lets say :
#Entity
class Book{
String name;
Author author;
}
#Entity
class Author{
String name;
City hometown;
}
#Entity
class City{
String cityName;
}
If i want to retrieve all the books, if i use classic JPA Repository and Spring Data and just do a findAll(), it will get me all the books with all the Authors with all their home towns. I know i can use #JsonIgnore, but i think that only prevents whats being returned, not whats being looked up in the database. And also i have methods that DO want to return both books and authors, so #JsonIgnore -ing does not work for me. Is there anything like this ? To tell Spring Data what to look up and what to return ? Any links or guides or methods i don't know of, would be appreciated.
Spring Data has the concept of 'projections' which allow you to return different representations of the same Entity.
Official Documentation:
Spring Data query methods usually return one or multiple instances of
the aggregate root managed by the repository. However, it might
sometimes be desirable to create projections based on certain
attributes of those types. Spring Data allows modeling dedicated
return types, to more selectively retrieve partial views of the
managed aggregates.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections
Where a Projection is a 'closed' projection (a projection interface whose accessor methods all match properties of the target aggregate) then the documentation notes that additionally:
Spring Data can optimize the query execution [to select only the relevant fields], because we know about
all the attributes that are needed to back the projection proxy
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections.interfaces.closed
Spring Data also allows for Projections to be specified dynamically at runtime. See further:
https://github.com/spring-projects/spring-data-commons/blob/master/src/main/asciidoc/repository-projections.adoc#dynamic-projections
First mark your relations as LAZY
Then specify what data needs to be fetched on a per-query basis.
See for example:
https://vladmihalcea.com/eager-fetching-is-a-code-smell/

Force new _id generation in embedded MongoDB documents

I am working with ASP.NET MVC 3, C# and MongoDB. I have a model with embedded documents, but I would like to auto-generate a new _id for each of my embedded documents.
I can do this in the code and set
Model._id = ObjectId.GenerateNewId();
But I would love it if I didn't have to worry about doing this and let MongoDB auto-generate the new _id for each embedded document.
I do not want to normalize out these embedded documents into a new collection, they make sense here, but I'd like to have a unique ID for them.
The only ObjectId that MongoDB "auto-generates" is the one it uses for the primary key: _id.
When you save a document, MongoDB knows basically nothing about "schema" or "embedded" documents or "arrays of sub-documents". There's no type-checking or schema validation, so there's no way to force the instantiation of the embedded IDs.
Your best bet is to wrap it up in the parent class. If those embedded documents have a specific class tied to them, you can put the GenerateNewId() in that constructor.

Resources