How can I register a custom object deserializer to the repository? - spring

In String Boot backend,
I have a Vehicle class.
Classes like Bike, Car, Bus will extend class Vehicle.
On firestore database, I store instances of Vehicle including Bike, Car, etc.... So I expect to get a collection of these documents to a String Boot backend using the Spring Data FirestoreReactiveRepository and the return type will be Vehicle? I guess. How can I register an object deserializer to this repository to get the correct object of correct type from firestore.
I have no idea how to do it, because the document barely mention it.
Currently, I just use firestore library, not Spring Data one, to retrieve data as HashMap then convert it to object using registered objectmapper.

Related

Add a dynamically created element to a REST API in Springboot

I am trying to create a database that will hold the prices of assets that are obtained from exchanges. I've created an Exchange class that holds variables that are the various prices. In my code, I have the following:
try{
Exchange Coinbase = new Exchange();
Coinbase.setName("Coinbase");
Coinbase.setBtcBuy(priceRequestCoinbase(btcBuy));
Coinbase.setBtcSell(priceRequestCoinbase(btcSell));
Coinbase.setEthBuy(priceRequestCoinbase(ethBuy));
Coinbase.setEthSell(priceRequestCoinbase(ethSell));
I am now just struggling to figure out how I would add this to my database so that it is accessible through api calls later on.
You can always convert this as a json string using objectmapper and store as text / json in your DB. The api can return this and directly convert to your exchange object.
Adding:
Better way would be to have an exchange table with your field names as columns. Create a repository class implementing jparepository for your exchange object. Annotate your exchange object with #entity annotation and autogenerated Id. Use the inbuilt jpa save method to save to db.
Also by Java standards the variable names should start with a lowercase (coinbase)

Handling filtering by a particular field in JPA Spring Boot

I want to implement a filtering feature based on the properties of an entity that I have stored in my db.
I'm using a JPA query to do so. The problem that I'm facing is concerned with entity manager which requires the class of the object that is required to return.
public List<CountryEntity> getSortedCountries(String field, String type) {
return entityManager.createQuery(GET_ALL_SORTED.concat(field).concat(" " + type), CountryEntity.class).getResultList();
}
When I select only one field, let's say the name of the country, the query returns a String and not an object of type CountryEntity.
What is the best approach to handle this problem? Should I create classes for every single case or is there another way that I'm missing?

Mongo ObjectId backward conversion from JSON to POJO

in my database I have user with ObjectId("5f78cd195a52a201fb117175").
Then I send it by Spring REST Controller to Angular Frontend and there my object id looks like this:
{date: 1601752345000, timestamp: 1601752345}
Afterwards in frontend I create product object, which contains field userId whose value is set to {date: 1601752345000, timestamp: 1601752345} . That object is sent to backend and later on is saved in db. The problem is that when it is converted by Jackson in Rest controller the userId field has value ObjectId("5f78cd19065ece5ade441e7a").
So from user with ObjectId("5f78cd195a52a201fb117175") I receive ObjectId("5f78cd19065ece5ade441e7a")
I dont have user with this second ObjectId so the field with userId contains no realtion to real user.
DO you know why it happens and how to deal with it ?
Jackson treats all objects like POJO types. By default, serialises all getter-s. Let's assume, that ObjectId instance in Java is represented by org.bson.types.ObjectId which has two getter-s:
getDate in your case date field in JSON
getTimestamp in your case timestamp field in JSON
These two fields will be serialised to JSON payload. Deserialisation process needs constructor and setters. I guess, in this case constructor ObjectId​(int timestamp, int counter) will be chosen (but I am not sure). You can try to create new instance of ObjectId using this constructor with values from your JSON payload.
When you use Jackson to serialise/deserialise types from 3-rd party libraries you can expect that there is a module implemented for this. Take a look on MongoJack:
Since MongoDB uses BSON, a binary form of JSON, to store its
documents, a JSON mapper is a perfect mechanism for mapping Java
objects to MongoDB documents. And the best Java JSON mapper is
Jackson. ...
You need to register this module and serialisation/deserialisation processes should work as expected.
See also:
How do you extract a timestamp from a MongoDB ObjectId in Spring Data MongoDB?
Binary JSON with bson4jackson

Expose custom query in Spring Boot Rest API with multiple joins

I have an Spring REST Api and a MySQL Database, now I would like to expose the result of an custom query with multiple joins.
I have tried multiple suggestions that I found online but none of them were working for me so far.
What I want to do is something like a read only DTO that has all the fields of my custom query so that in the end I have one api page exposing the DTO data as JSON so my client (Angular) can read the data from there.
I already tried to:
create an #RestController with an injected EntityManager that executes a NativeQuery and then populates the DTO with the returned data but since my DTO is no Entity I get an Hibernate Mapping Exception
create a custom Repository and its Impl but with a similar outcome
place the Query inside an existing #Entity that is part of the Query statement
What am I missing here? Do I have to annotate my DTO maybe? Cuttently it's just a POJO, I think the #Entity annotation is not the right thing here since I don't want a Table created from my DTO.
Fixed it by letting the Query return an Array of type Object and afterwards mapping it to the DTO Constructor.

How to map a Spring Data JPA repository entity into a view model?

Here is the situation, I want to fetch an entity from database and map it to a new view domain model which has more or less properties, if this view model has more properties, signs the extra properties with default value. I want a map technique in JPA to complete this, which is similar to MyBatis mapping mechanism.
So how to do it?
Just load the entity, copy it over in the new entity, fill the unset properties with the desired default values and store it using JPA (possibly via Spring Data JPA).
For copying over the data from one entity to another you might want to look int Dozer or similar libraries.
You could also misuse Spring Data's projection support to query the original entity, but return it as the target entity with methods similar to the following:
interface SourceRepository<Source, Long> extends CrudRepository<Source, Long> {
List<Target> findTargetBy();
}
The resulting Target entities then could be stored again using another repository (you might have to set version and id properties to null to make it clear to the framework that these are new entities.

Resources