Convert Spring Entity objects to modified JSON Object - spring-mvc

I am having a few tables in my DB. Employee, Address, Phone_id
Table Employee
====================
ID | Emp_Name | Address_id | Phones_id
Table Address
====================
ID | Block_no | City | State
Table Phone_id
====================
ID | Phone_1 | Phone_2 | Phone_3
When I display the JSON received directly from repository, it works, but not in the format expected by UI.
I wish to make some changes to the received JSON. Basically, transform it and then provide response over REST.
So my questions are:
Is there any Spring way to solve my requirement. So that I can just map my entity class to some JSON class.
Is there any design pattern that can be used in such a scenario.
Thanks a bunch!

It is advisable to keep you #Entity classes and your JSON representation classes separated.
Let's say you have #Entity class Employee.
One option is to use the same Employee class to describe your database entity (using let's say JPA annotations) and then use the same Employee class to describe the JSON you want to return to the client (using let's say Jackson annotations).
That's considered bad practice for various reasons.
Most common one is that most of the time you don't want all your entities to be mapped 1:1 to your JSON response.
In order to deal with this, a common approach is to create a separate Employee class to describe your JSON representation. You can call it EmployeeDto.
Then you have to write a custom logic that maps #Entity Employee to EmployeeDto.
You can use static factory method like so:
//Persistence layer class
#Entity
public class Employee {
#Id
#GeneratedValue
#Column(name = "id")
private Long id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
//getters/setters
}
//REST layer class
public class EmployeeDto {
#JsonProperty("first_name")
private String firstName;
#JsonProperty("last_name")
private String lastName;
public EmployeeDto() {}
// you can do any transforamtion/validation here
public static EmployeeDto fromEntity(Employee employee){
EmployeeDto dto = new EmployeeDto();
dto.setFirstName(employee.getFirstName);
dto.setLastName(employee.getLastName);
}
//getters/setters
}
Then your controller will return List<EmployeeDto> instead of #Entity Employee.
UPDATE:
Spring doesn't provide automatic conversion mechanism between DTO and Entity object. I think it depends on the complexity of the classes and number of pairs (DTO/Entity), but most of the time it's easy enough to implement the conversion yourself.
Of course there are libraries out there, which provide some level of automation with the mapping:
ModelMapper
Orica

Related

How to prove JPA Enity must not be final class with Hibernate 5

JSR 338: JavaTM Persistence API 2.1 Specification > 2.1 The Entity Class specifies:
The entity class must not be final. No methods or persistent instance variables of the entity class may be final.
So I tried with Hibernate 5.2.18.Final to prove it by setting an entity class as final:
#EqualsAndHashCode
#Getter
#Setter
#Entity
public final class City {
#Id
#SequenceGenerator(name="city_sequence", sequenceName="city_seq", initialValue=0, allocationSize=25)
#GeneratedValue(strategy=SEQUENCE, generator="city_sequence")
private int id;
#Column(length=20, nullable=false)
private String city;
#ManyToOne(fetch = FetchType.LAZY)
private Province province;
}
However, the result is out of my expectation: the corresponding table can be generated and new instance of City can be persisted to the database, meaning my code proves that entity class can be final
Question: Is there any better way to prove the entity class must not be final? Isn't it a hard-and-fast rule as it is in the specification?

Spring Data JPA method for deleting using a two fields in the embaddable key

THis is the main entity class, which is having an embeddedId
public class LabResHivMutation implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private LabResHivMutationPK id;
private String comments;
#Column(name="MUTATION_TYPE_ID")
private BigDecimal mutationTypeId;
#Column(name="VALUE")
private String value;
}
This is the embeddable key
#Embeddable
public class LabResHivMutationPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
#Column(name="TO_INST")
private Long toInst;
#Column(name="REL_INVSTID")
private long relInvstid;
#Column(name="MUTATION_ID")
private long mutationId;
}
Is there any delete methos available in spring data Jpa to delete based on only two of the embaddable key(toInst,relInvstid).
I still can write a JPQL query to delete it. My question is there any method available for this.
like deleteById ?
Yes there is, repo.deleteByIdToInstAndIdRelInvstid(toInst,relInnvstid)
As you see you have to specify deleteByIdToInst , this is how you reference a field of an embedded ID , the same as you would reference a field of a foreign relation. Here Id matches your field naming
#EmbeddedId
private LabResHivMutationPK id;
There are two ways to delete an entity: either using its own "JPA Repository derived delete method" long deleteByFirstIdAndSecondId(long firstId , secondId)
In your service you can simply call it : repository.deleteByFirstIdAndSecondId(long firstId , secondId)
Another way is through the parent entity by excluding the child entity (or entities depends on the relation type).
User underscore '_' when entity will have multiple keys with using #Embedded keys.
example :repository.deleteByid_toInst();

Spring Data Jpa: save an entity with #ManyToOne

I m working with spring boot, i have these two classes
#Entity
#Table(name="products")
public class Product implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long idProduit;
//other attributes..
#ManyToOne
#JoinColumn(name="idCategory")
private Category category;
and category class :
#Entity
public class Category implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long idcategory;
//attributes...
#OneToMany(mappedBy="category")
private Collection<Product> products;
i want to code a methode to save product
public long saveProduct(Product p, Long idCat)
Is there a method defined in JpaRepository which can do this or, should i add a service Layer and define my method like below or define it a custom method in Repository ?
public long saveProduct(Product p, Long idCat){
Category c=getCategory(idCat);
p.setCategory(c);
em.persist(p);
return p.getIdProduct();
}
I think you should add a service Layer and define a transactional method in order to handle exceptions like CategoryNotFoundException (when Category c=getCategory(idCat) fires one) ,
DataIntegrityViolationException....
Building a solution without a service Layer isn't a good practice, since you will have to handle transactions and propagations manually and you will risk having dirty reads.

Hibernate search with lucene for two tables

I have two tables CatalogueBase and CatalogueCopydetails now i am using Hibernate search for CatalogueBase table but i wanted to search even in CatalogueCopydetails table. This two tables are related with #ManyToOne (i.e CatalogueCopydetails using CatalogueBase id as foreign key), hear for one entry of CatalogueBase their will be 'n' numbers of CatalogueCopydetails
CatalogueBase POJO Class
#Indexed
#JsonAutoDetect
#Entity
#Table(name="catalogueBase")
public class CatalogueBase extends BaseObject implements Serializable {
private Long id;
......
#Id
#GeneratedValue
#Column(name="id")
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
....
CatalogueCopydetails POJO Class
#JsonAutoDetect
#Entity
#Table(name="cataloguecopydetails")
public class CatalogueCopyDetails extends BaseObject implements Serializable {
private CatalogueBase catalogueBase;
......
#ManyToOne
#JoinColumn(name="cataloguebaseid" , insertable=true, updatable=true,nullable=true)
public CatalogueBase getCatalogueBase() {
return catalogueBase;
}
public void setCatalogueBase(CatalogueBase catalogueBase) {
this.catalogueBase = catalogueBase;
}
......
at least how can i use #IndexedEmbedded for this scenario (i don't think i can use #IndexedEmbedded because CatalogueBase have no relation to CatalogueCopyDetails like OneToOne or OneToMany etc only CatalogueCopyDetails references CatalogueBase )
how can i do this..?, any help will be appreciated, Thanks.
The easiest way would of course be to make the relation bidirectional. Is there a good reason why you don't want to do that? The other thing you could do is to add #Indexed to CatalogueCopyDetails as well and use #IndexedEmbedded on CatalogueBase. You could then write a query using the CatalogueCopyDetails index. Whether this works will depend on your use case and what you actually want as result of query.

Am I best off using a class or just the ID for an entity framework foreign key?

Basically put, I have an "Identity" table that has an ID and username, I have another table that has entries "owned" by a person, for that reason, I need to have a FK that links to the Identity table.
For example: Class "Identity" - int ID, string username.
I was just wondering which of the following is best:
Class "test" - int ID, string data, Identity identity
Class "test" - int ID, string data, int identity_id - with an annotation defining as foreign key.
I personally use the first, and seen that EF basically does the second behind the scene, but I was just wondering what the advantages/disadvantages are and what is best?
From the object oriented perspective the first is better because you have reference to the related object and it is what you expect when working with objects. In database this is performed by foreign key which defines relation between two records.
Entity framework offers both correct object oriented approach (the first one) and the approach where you include foreign key property in the entity as well. The reason is that exposing FK property will make some operations much more easier. Most common solution for the second approach is:
public class Test
{
public int Id { get; set; }
public string Data { get; set; }
[ForeignKey("Identity")]
public int IdentityId { get; set; }
public Identity Identity { get; set; }
}
You have both access to FK property and the entity. Those approaches have names: Independent association (the first one) and Foreign key association (the second one). There are more differences between them - I described them in another answer.

Resources