Mapping single bean class to multiple tables in hibernate - java

I have developed a spring rest service which will accepts a json input and freeze the details in to database and return the status as json output. everything is working fine.
now i need to update the service with the new requirement, i will get address details of the user and i need to update the address table as well. My question is
1) How to change the input request currently my controller is as follows
#Requestmappping(value="/register", metod=RequestMethod.POST)
public #ResponseBody ResponseEntity userRegis(#RequestBody UserBean userdetails){
}
2) How to change the UserBean format. Currently it is mapping to one single table. Now i need to update the bean with address fields. and i need to map the address fields to new table.
please help on this.

What you are referring to in composition in OOP. So, basically user has address or addresses.
class User {
....
private Address addres;
//private List<Address> addres; use something like this if user has multiple addesses
}
class Address {
}
And offcourse you would not want to map same bean to multiple tables or something like that. The above relation is simple parent child relation. Read here

Related

How can convert DTO to Entity in Spring boot?

I looked for countless questions.
But most of the questions were as follows.
Entity -> Dto
Entity and Dto have the same attribute value.
but I don't want this.
I wonder how I can convert Dto to Entity when if property value present in Entity did not exist in Dto.
Some Code
dosen't specify the codes for the [annotations, Lombok, jpa, ...etc]
but it exists!
User Entity
class User {
Long id,
String username,
String email,
String password
}
UserDto
class UserDto {
String email
}
Post Entity
class Post {
Long id,
String title,
User user
}
PostDto
class PostDto {
Long id,
String title,
String username
}
UserService
...
UserDto findUser(id: Long) {
...
}
...
PostService
...
PostDto savePost(Post post) {
...
}
...
PostController
...
PostDto createPost(#RequestBody PostDto postDto) {
// spring security
Long userId = XXX.getUserId()
....
UserDto userDto = userService.findUser(userId)
// HERE !! what can i do ??
// How can i convert userDto to user ?
Post post = new Post(postDto.title, user)
PostDto newPost = postService.savePost(post)
}
...
Question
All methods of userService return in DTO.
how can I set user entity in Post Entity?
I received a userDto return which has only username.
What should I do at times like this?
The repository is not being called directly from the controller.
The service would like to return the DTO unconditionally.
Should I create an additional Dto that has the same properties as user entity?
Normally I implemented my class in following manner,
Entity : Contain all data related to your actual database object. (Additional data by #transient annotation)
DTO : Customize class which creates to provides compatibility between Entity and required JSON.
Mapper : It can convert Entity to DTO and vice versa.
In sort, Create entity for database object, n numbers of DTO for verity of need and using mapper class convert it to appropriate type and write this terms in your service class. So based on your need create DTO and in service class implement logic for get them all together.
(In best way use interface or inheritance when wants to bind multiple DTO in single entity or scattered it.)
Now comes to your question,
I wonder how I can convert DTO to Entity when if property value present in Entity did not exist in DTO.
Answer : Convert it using Mapper class. As per I define above Entity is database object and DTO is expected JSON. So doesn't matter it compulsory exist in your DTO. You can customize DTO as per your need.
The repository is not being called directly from the controller.
Answer : As obvious you have to do that and right way to implementation.
Should I create an additional DTO that has the same properties as user entity?
java
Answer : Yes you can but if it compulsory required. My suggestion is follow structure as I defined earlier it becomes helpful in future also, Suppose new kind of data you need you just have to add one function in mapper class and it return data accordingly, you also modify from single place and use every where.
This suggestion for based your code.
Move your all logical code controller to service class
In service class fire query and contain data of userDTO.
UserDto userDto = userService.findUser(userId)
It gives you email. Based on this fire another query for fetch user.
My personal suggestion as developer,
Create one JHipster project once and check their flow it gives you good idea regarding how to create structure in professional way.

how to validate spring model object with different attribute requirements different method calls?

we are using single model class in spring controller say
Student(id,firstname,lastname);
Now my controller have two methods
get student details where we pass Student object with id only.(only Id require)
update student details with all details id,firstname,lastname (where we use id for reference to update names)
in both controller methods I want to use spring validator so how can I write validated method for both controller methods as I required only id attribute to get student details and in other I want all three attributes to updated student details.
we are not using spring boot.
I always use dtos (data transfer Objects) for models that are sent by the client and separate models for responses.
That has many advantages. The incoming api models are decoupelt from the models that are used in your application. In addition, with the dto you just provide a model with the minimum of attributes a client may send to the api. And to adress your question you can verify them separatere.
I don‘t think you want your client to update the students id. So for your model use a dto that has the same attributes like a full student object but without the id Field.

Spring Framework - Multiple ModelAttributes of Same Type

I am working on a checkout page that requires a shipping address and a billing address. This integrates with a third-party library which has these both implemented as the same type: Address. What I need to be able to do is something like:
#RequestMapping(method = RequestMethod.POST)
#ResponseBody
public Response createOrder(
#ModelAttribute("customer") Customer customer,
#ModelAttribute("shipping") Address shippingAddress,
#ModelAttribute("payment") Payment paymentInformation,
#ModelAttribute("billing") Address billingAddress
) {
// Create the order
}
I am stuck on how to send two separate models of the same exact type over to my Spring application in a way that makes this work. I could potentially make facade models and map them to the real ones inside of the controller, but I would prefer not to go down that route if I can avoid it.
Edit: Changed the model attribute names to hopefully make the problem area more clear.
Instead of creating separate model attributes for each type, create an Order object and model attribute 'order.'
//Order class
private Customer customer;
private Address shippingAddress;
private Payment paymentInformation;
private Address billingAddress
..
public Response createOrder(
#ModelAttribute("order") Order order) {
// Create the order
}
Then the request would look like
shippingAddress.city=foo&billingAddress.city=bar

How to load missing object attributes before persisting?

I have a question about Jackson and Hibernate. My application is based on rest and objects are transferred between frontend and backend as json, so I have some situations when some object's attributes are missing when I deserialize json to java object and I'd like to load those attributes before persisting changes (because I don't want to lose that data from database). Has anybody any ideas to solve this problem?
Edit
I am not sure that my question has understood right. So I give simple example, what I try to say.
So I have following Java class:
#Entity
#Table( name = "employees" )
public class Employee extends BaseEntity<Long> {
private String lastName;
private String firstName;
#Embedded
private Address address;
//... a lot of other attributes and methods..
}
Now I get json data from frontend, which is something like this:
{
"id":17,
"lastName":"Smith",
"firtName":"John"
}
Next I want to save these changes to database but my deserialized java entity is totally incomplete, there are a lot of missing attributes and references (values are nulls). How can I load those missing attribute values before persisting object, without losing those new values that I got from UI?
I have tried to use EntityManager's merge-method but it didn't work...
Load the Data from DB (if the record already exists), do a merge & save.
You can map multiple DTOs as JPA #Entities to the same database table. When you save one such DTO, only it's fields are propagated to the DB, without interfering with other database column the current DTO hasn't mapped.

Expressing Audit functionality with JPA annotations

I'm in the middle of fumbling around with JPA. I've so far successfully created an entity representing the user data and a stateless bean for the access to the user data.
The data the users can work on is like this (SQLFiddle link):
CREATE TABLE data
(
email character varying(128) NOT NULL,
data character varying(128) NOT NULL,
lastchange timestamp NOT NULL,
CONSTRAINT email_data PRIMARY KEY (email,data)
);
The idea is to save the unaltered, current version for all users with an empty email key. Then, when a user alters the data and creates an auditable version, the email field is filled with the users email. This way, each user can alter their copy of the data. The merging is a problem for a later date and not part of my question.
Now, I have the entities already in place. I created a stateless bean to load/save/find the data records by using the EntityManager. The logic to load the user specific version first, then load the unaltered version if the user has no user specific version still eludes me.
Consider this part of the bean:
#Stateless
public class DataBean {
#PersistenceContext(unitName = "authPU")
private EntityManager em;
public List<DataEntry> findAll() {
TypedQuery<DataEntry> query = em.createQuery("SELECT d FROM data d", DataEntry.class);
List<DataEntry> list = query.getResultList();
return query.getResultList();
}
...
}
How do I inject the user information into this class? I need to get the data for the current user first, then get the data for all users if there's no user-specific data available.
You could use standard EJB authentication. Then you can call SessionContext.getCallerPrincipal() in your session bean to get a user ID. Use this user ID to query the database.
In this case you have to add another column to your table (containing the user ID), if the authentication user ID does not equal the email address.
Far simpler (but less elegant) is to add the email address to the arguments of your EJB service method: Just make it part of the public API.

Categories

Resources