Retrieve logged user object and save it as a foreign key - java

While saving some data from the form I also need to add FK to the Record table. FK is User.Id.
I know how to save data from the input field on the form, but how can I set FK (int value) to this:
#ManyToOne
#JoinColumn(name = "id")
#Cascade({CascadeType.ALL})
private User user;
Is there some way to retrieve object which relates to logged user and make something like this: record.setUser(user)?
I've googled it but I didn't manage to find how to achive this.
This is my entity class.
#Entity
public class Record implements java.io.Serializable{
#Id
#GeneratedValue
private int recordId;
private String recordName;
private String recordComment;
private Date recordDate;
private Integer price;
#ManyToOne
#JoinColumn(name = "userId", insertable = true, updatable = false)
#Cascade({CascadeType.ALL})
private User user;
......
}
#Entity
#Table(name = "system_user")
public class User implements java.io.Serializable{
#Id
#GeneratedValue
private int userId;
#NotEmpty
#Email
private String email;
#Size(min=2, max=30)
private String name;
private String enabled;
#NotEmpty
private String password;
private String confirmPassword;
#Enumerated(EnumType.STRING)
#Column(name = "user_role")
private Role role;
#OneToMany(fetch = FetchType.EAGER,mappedBy = "user", orphanRemoval=true)
#Cascade({CascadeType.ALL})
private List<Record> records;
public void addToRecord(Record record) {
record.setUser(this);
this.records.add(record);
}
....
}
This is how I save data to DB:
#RequestMapping(value = "/protected/add", method = RequestMethod.POST)
public String addCost (#ModelAttribute("record") Record record,HttpSession session){
User user = userManager.getUserObject(userManager.getUserId(session.getAttribute("currentUser").toString()));
user.addToRecord(record);
recordService.addRecord(record);
return "redirect:/protected/purse";
}
DAO:
public void addRecord(Record record) {
sessionFactory.getCurrentSession().save(record);
}
UPDATE: problem was partially solved, code above works fine for me.

You also need to create User object and set the user object in a Record object using the below code
record.setUser(userObj);
and user foreign key will be automatically saved in database.

Related

Cannot update a single entity in Many-to-Many relationship

I am currently making project which should have Many-To-Many relationship between groups and users. I should be able to update an user and add one. I have no troubles with adding an user, it gets saved properly. However, when I try to update user, it gives an error that definitely has something to do with that hibernate tries to save groups information. Here is my code.
User Entity
#Entity
#Table(name = "user")
public class User {
#Id
#Column(name = "email")
private String email;
#Column(name = "firstname")
private String name;
#Column(name = "lastname")
private String surname;
#Column(name = "age")
private int age;
#Column(name = "gender")
private String gender;
#ManyToMany
#JoinTable(
name = "user_group"
, joinColumns = #JoinColumn(name = "email")
, inverseJoinColumns = #JoinColumn(name = "group_id")
)
Group entity
#Entity
#Table(name = "category")
public class Group {
#Id
#Column(name = "group_name")
private String name;
#Column(name = "description")
private String description;
#ManyToMany(mappedBy = "groupList")
private List<User> userList = new ArrayList<User>();
Controller save method
#PostMapping("/addUser")
public String addUser(#ModelAttribute("user") User user) {
service.saveUser(user);
return "redirect:/allUsers";
}
Service save method
#Override
#Transactional
public void saveUser(User user) {
userDAO.saveUser(user);
}
DAO save method
#Override
public void saveUser(User user) {
entityManager.merge(user);
}
java.sql.SQLSyntaxErrorException: Unknown column 'group1_.description' in 'field list
The problem was that I altered my column names in DB but forgot to update it in Entity class. Got to be careful next time:)

#GetMapping used to retrive item gives a responce of infinite loop of foreignkey object

i am new in spring boot and i could not find solution for this for a day now.
#GetMapping used to retrive item gives a responce of infinite loop of foreignkey object "user".
why am i getting this infinite loop?
how to fix it?
user object in infinite loop(the problem)
result that i want
item entity
#Entity
public class Item{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long ItemId;
#ManyToOne
#JoinColumn(name = "owner_id")
private User user;
private String ItemName;
// #Column(columnDefinition="text")
private String Description;
private double Price;
private int AvailableQuantity;
private double shippingWeight;
// #Transient
// private MultipartFile Picture;
#Enumerated(value = EnumType.STRING)
private Category category;
#OneToMany(mappedBy = "item")
#JsonIgnore
private List<CartItem> CartItemList;
}
user entity
#Entity
#Table(name = "Utilisateur")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idU;
private String username;
private String password;
private String firstname;
private String lastname;
private String gender;
private Long phone;
private String adress;
#Temporal(TemporalType.DATE)
private Date dateofbirth;
private int rating;
private String email;
public Role role;
private Integer status;
#OneToMany(mappedBy = "user")
private List<Item> ItemList;
}
item service
#Service
public class ItemService implements ItemServiceInterface{
#Autowired
ItemRepository itemrepository;
public Optional<Item> getItemById(long id){
return itemrepository.findById(id);
}
}
item controller
#RestController
public class ItemControl {
#Autowired
ItemServiceInterface itemservice;
#GetMapping("/getitem/{id}")
public Optional<Item> getitembyid(#PathVariable Long id) {
return itemservice.getItemById(id);
}
}
You can use combination of #JsonManagedReference and #JsonBackReference to discourage Jackson from infinite serialization.
#Entity
#Table(name = "Utilisateur")
public class User {
// omitted
#JsonManagedReference
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Item> ItemList;
}
#Entity
public class Item{
// omitted
#JsonBackReference
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "owner_id")
private User user;
}
More details could be found here https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
You can make use of lazy loading to cut the dependency loop between user and item. However, following that approach might potentially affect other parts of your projects because other codes might use the entity with an assumption that item list in user entity is already eager fetched.
A better way is not return the entity object directly to the REST response. You can define a data model for the rest response and convert the entity to that model in your service class. This way, you can completely control what to return and not to.
Another approach if you still want to use the entity as response: https://www.baeldung.com/spring-data-jpa-named-entity-graphs. This way, you can define when to use the lazy load with each specific query.

Hibernate One-to-Many Mapping Using Annotations; I'm trying to use foreign key association to save a user id in another table.

I'm not able to make this work.
I've also tried using a join table, but the result is the same. The user id that I need to appear in the table commissions doesn't.
Here's how I've created the entities.
For User and UserRole I've used a join table and it works.
I've tried to do the same for Commission but with no success (the joining table remained empty) so I tried like below with foreign key association.
User:
#Entity
#Table(name="USERS")
public class User implements Serializable{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#NotEmpty
#Column(name="USERNAME", unique=true, nullable=false)
private String username;
#NotEmpty
#Column(name="PASSWORD", nullable=false)
private String password;
#NotEmpty
#Column(name="FIRST_NAME", nullable=false)
private String firstName;
#NotEmpty
#Column(name="LAST_NAME", nullable=false)
private String lastName;
#NotEmpty
#Column(name="EMAIL", nullable=false)
private String email;
#NotEmpty
#ManyToMany(targetEntity=UserRole.class, fetch = FetchType.LAZY)
#JoinTable(name = "USERS_USER_ROLE",
joinColumns = { #JoinColumn(name = "USER_ID") },
inverseJoinColumns = { #JoinColumn(name = "USER_ROLE_ID") })
private Set<UserRole> userRoles = new HashSet<UserRole>();
#OneToMany(fetch = FetchType.LAZY, mappedBy="user")
private Set<Commission> commissions;
//getters and setters
Commission:
#Entity
#Table(name="COMMISSIONS")
public class Commission implements Serializable{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#NotEmpty
#Column(name="ORDER_NAME", unique=true, nullable=false)
private String orderName;
#NotEmpty
#Column(name="ORDER_DETAILS", unique=true, nullable=false)
private String orderDetails;
#Column(name="ORDER_STATUS", unique=true, nullable=false)
private String orderStatus;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "USER_ID", nullable = false)
private User user;
//getters and setters
UserRole:
#Entity
#Table(name="USER_ROLE")
public class UserRole implements Serializable{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name="ROLE", length=15, unique=true, nullable=true)
private String role = UserRoleType.USER.getUserRoleType(); // getUserRoleType is defined in an enum with 'ADMIN', 'DBA', 'USER'
//getters and setters
In the UserDAO and CommissionDAO I've used SessionFactory to save the entities.
Extract from the abstract class which is extended by UserDAO and CommissionDAO.
#Autowired
private SessionFactory sessionFactory;
protected Session getSession(){
return sessionFactory.getCurrentSession();
}
public void persist(T entity) {
getSession().save(entity);
}
When I create a new user, everything works fine. The joining table has the correct id's added to it.
However...
When I add a new commission, the commission itself is added in the commissions table but the user_id remains null.
I'm new to hibernate and with this "project" of mine, I think I might've bit a more than I can chew.
Maybe the issue is somewhere else in the code and not here?
Anyhow, I'm in a bit of a bind and could use your expertise guys. Cheers!
Thanks Rossi Robinsion. That was it.
I missed to associate the user in my Commission controller.
This was before.
#RequestMapping(value = { "/newcommission" }, method = RequestMethod.POST)
public String saveCommission(#Valid Commission commission, BindingResult result, ModelMap model) {
if (result.hasErrors()) {
return "commissioncreation";
}
if(!commissionService.isUserOrderNameUnique(commission.getId(), commission.getOrderName())){
FieldError orderNameError =new FieldError("commission","orderName",
messageSource.getMessage("non.unique.orderName",
new String[]{commission.getOrderName()}, Locale.getDefault()));
result.addError(orderNameError);
return "commissioncreation";
}
commissionService.saveCommission(commission);
model.addAttribute("success", "Your commission was successfully created.");
model.addAttribute("loggedinuser", getPrincipal());
return "commissioncreationsuccess";
}
This is after.
#RequestMapping(value = { "/newcommission" }, method = RequestMethod.POST)
public String saveCommission(#Valid Commission commission, BindingResult result, ModelMap model) {
if (result.hasErrors()) {
return "commissioncreation";
}
if(!commissionService.isUserOrderNameUnique(commission.getId(), commission.getOrderName())){
FieldError orderNameError =new FieldError("commission","orderName",
messageSource.getMessage("non.unique.orderName",
new String[]{commission.getOrderName()}, Locale.getDefault()));
result.addError(orderNameError);
return "commissioncreation";
}
User user = userService.findByUsername(getPrincipal()); // associated the user properly.
commission.setUser(user);
commissionService.saveCommission(commission);
model.addAttribute("success", "Your commission was successfully created.");
model.addAttribute("loggedinuser", getPrincipal());
return "commissioncreationsuccess";
}
I don't know how I could miss this... sigh...
Thanks mate!

Trouble with hibernate and json

So i have a user and a client.The user can have multiple clients.But json cannot return a value user.
So i did something like this :
#Column
private Integer fkIdUser ;
But i'm new to hibernate and i'm wondering if this is the right way of doing this. Or do i need to use a class with a many to one annotation but how would i do this with json ?
User class
public class User {
public static User globalUser;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_user")
private Integer id;
#Column(unique = true)
private String email;
Then the Client class
#Entity
#Table(name ="tbl_clients")
#Access(value = AccessType.FIELD)
public class Client {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_client")
private Integer id;
/* This works
#Column
private Integer fkIdUser ;
*/
// This does not
#ManyToOne
#JoinColumn(name = "fk_id_user")
private User user;
I'm using this function in the ClientController to store the client to the database
#RequestMapping(value = "/addclient",method = RequestMethod.POST)
public void addClient(#RequestBody Client client) {
clientDao.save(client);
}
You have to use the same name of the column in the #JoinColumn name. Since you are using fkIdUser as the variable and it works, I suppose this is your column name. Then your mapping should be like this:
#ManyToOne
#JoinColumn(name = "fkIdUser")
private User user;

#OneToOne Hibernate with annotations. Can't properly save

I can't make my foreign keys auto generate using hibernate and jpa with annotations. Everything seems ok, The entries are saved in database. All the date come from one form which, when submited creates an User object with ModelAttribute and then saves it in Database.
Here are my beans. Anything else i should add ?
#Entity
#Table(name="adress")
public class Adress implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="adress_id")
private Integer adressId;
#NotBlank(message="The city must be completed")
#Column(name="city")
#Size(min=5,max=30)
private String city;
#NotBlank(message="The street must be completed")
#Column(name="street")
#Size(min=5,max=30)
private String street;
#NotNull(message="The street number must be completed")
#NumberFormat
#Column(name="street_no")
private Integer streetNo;
#OneToOne
#JoinColumn(name="user_id")
private User user;}
and the other one:
#Entity
#Table(name="users")
public class User implements Serializable {
#Id
#Column(name="user_id")
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer userId;
#NotBlank(message="Username can't be blank")
#Size(min=5,max=30)
#Column(name="username")
private String username;
#NotBlank(message="Password field can't be blank")
#Size(min=5,max=30)
#Column(name="password")
private String password;
#NumberFormat
#NotNull(message="Age field must not be blank")
#Column(name="age")
private Integer age;
#Column(name="message")
#Size(min=0,max=100)
private String message;
#Column(name="date")
#DateTimeFormat(pattern="dd/mm/yyyy")
private Date dateCreated;
#OneToOne(mappedBy="user",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
private Adress adress;
+getters and setters for them
public void save(T entity){
sessionFactory.getCurrentSession().save(entity);
}
If I understand you correctly and you're trying to get Hibernate to set the foreign key on your related record this might help. Try getting rid of mappedBy and instead specify the JoinColumn. This works for me on a one to many:
The order:
#Entity
#Table(name = "`order`")
public class Order implements Serializable {
#Id
#GeneratedValue
private Long id;
// Order columns...
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "order_id")
private Set<Item> items;
}
The item:
#Entity
#Table(name = "item")
public class Item implements Serializable {
#Id
#GeneratedValue
private Long id;
// Item columns...
#ManyToOne(optional = false)
#JoinColumn(name = "order_id", referencedColumnName = "id", nullable = false)
private Order order;
}
in adress class
#OneToOne(mappedBy="adress")
private User user;
and in user class
#OneToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER,optional=false)
#PrimaryKeyJoinColumn
private Adress adress;

Categories