...
is my code
#ManyToOne
#JoinColumn(name = "destination_country_id", referencedColumnName = "id", table = "countries", insertable = false, updatable = false)
public Country country;
...
is the result
"id": 139,
"country": {
"id": 1,
"iso": "AU",
"name": "Australia",
},
"country_id": 1
...
I hope the result is
"id": 139,
"country": "australia",
"country_id": 1,
...
add this code and change to private in var country
#Column(name = "name", table = "countries")
public String country_name;
this is a new my code
#ManyToOne
#JoinColumn(name = "destination_country_id", referencedColumnName = "id", table = "countries", insertable = false, updatable = false)
private Country country;
#Column(name = "name", table = "countries")
public String country_name;
Related
I want the Employee object to only display the id property when adding a CV. When I put #JsonIgnore on the employee object in the CV, the id doesn't come either. How can I hide property that I do not want to appear in employee class (password, national identity) on the CV class?
Cv Class :
#Entity
#Table(name = "cvs")
#Data
#AllArgsConstructor
#NoArgsConstructor
public class CV {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#OneToOne
#JoinColumn(name = "employee_id")
private Employee employee;
#OneToMany(mappedBy = "cv", cascade = CascadeType.ALL, orphanRemoval = true)
List<Education> educations;
#OneToMany(mappedBy = "cv", cascade = CascadeType.ALL, orphanRemoval = true)
List<Work> works;
#OneToMany(mappedBy = "cv", cascade = CascadeType.ALL, orphanRemoval = true)
List<Languege> langueges;
#OneToMany(mappedBy = "cv", cascade = CascadeType.ALL, orphanRemoval = true)
List<Technology> technologies;
#Column(name = "github")
private String github;
#Column(name = "linkedin")
private String linkedin;
#NotNull
#NotBlank
#Column(name = "cover_letter")
private String coverLetter;
#Column(name = "photo")
private String photo;
}
Employee Class :
#Data
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "employees")
#Entity
#PrimaryKeyJoinColumn(name = "user_id", referencedColumnName = "id")
public class Employee extends User {
#NotNull
#NotBlank
#Column(name = "first_name", length = 50)
private String firstName;
#NotNull
#NotBlank
#Column(name = "last_name", length = 50)
private String lastName;
#NotNull
#NotBlank
#Column(name = "national_identity", length = 11)
private String nationalIdentity;
#NotNull
#Column(name = "year_of_birth")
private int yearOfBirth;
#JsonIgnore
#OneToOne(mappedBy = "employee")
private CV cv;
}
I read data this format;
{
"id": 0,
"employee": {
"id": 0, //visible
"email": "string", //not visible
"password": "string", //not visible
"firstName": "string",
"lastName": "string",
"nationalIdentity": "string", //not visible
"yearOfBirth": 0 //not visible
},
"educations": [
{
"id": 0,
"schoolName": "string",
"department": "string",
"startingDate": "2022-02-11",
"graduationDate": "2022-02-11"
}
],
"works": [
{
"id": 0,
"workplace": "string",
"job": {
"id": 0,
"jobName": "string"
},
"startingDate": "2022-02-11",
"endDate": "2022-02-11"
}
],
"langueges": [
{
"id": 0,
"languege": "string",
"level": 0
}
],
"technologies": [
{
"id": 0,
"technology": "string"
}
],
"github": "string",
"linkedin": "string",
"coverLetter": "string",
"photo": "string"
}
You can use a custom serializer that you would use on your CV employee field : #JsonSerialize(using = CustomEmployeeSerializer.class)
public class CustomEmployeeSerializer extends SerializerBase<Employee> {
public CustomEmployeeSerializer() {
super(Employee.class, true);
}
#Override
public void serialize(Employee employee, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeString(employee.getId());
}
I have created a many to many relationship. It is returning the data correctly. However, I noticed that if the data exist in canUse section of the json and has been called before by another Player, it does not print the data again only the new values are printed.
JOSN
[
{
"id": 12,
"firstname": "asdfghjkl ",
"surname": "asda",
"canUse": [
{
"id": 0,
"techniqueName": "JAVA"
},
{
"id": 1,
"techniqueName": "PHP"
},
{
"id": 2,
"techniqueName": "PYTHON"
}
]
},
{
"id": 49,
"firstname": "asc",
"surname": "as",
"canUse": []
},
{
"id": 90,
"firstname": "LOL",
"surname": "LOL",
"canUse": []
}*,
{
"id": 91,
"firstname": "Kareem",
"surname": "LOL",
"canUse": [
1,
2,
{
"id": 3,
"techniqueName": "HASKELL"
}
]
},*
{
"id": 92,
"firstname": "Omar",
"surname": "LOL",
"canUse": []
}
]
Player entity
#Entity
#Table(name = "players")
#EntityListeners(AuditingEntityListener.class)
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Players {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="player_id")
private int id;
private String firstname;
private String surname;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(
name = "able_to_use",
joinColumns = {#JoinColumn(name = "player_id", referencedColumnName = "player_id")},
inverseJoinColumns = {#JoinColumn(name = "technique_id", referencedColumnName = "id")}
)
private List<Technique> canUse;
//Getters and Setters
Technique entity
#Entity
#Table(name = "technique")
#EntityListeners(AuditingEntityListener.class)
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Technique {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column(name = "technique_name")
private String techniqueName;
#JsonIgnore
#ManyToMany(mappedBy = "canUse", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Players> ableToUse;
//Getters and Setters
Thank you in advance, the problem is occurring for player with ID 91. this player should also print PHP and PYTHON but only the ID is printed.
I need return this Json to my project:
{
"data": {
"id": 1,
"username": "renato",
"name": "Renato",
"email": "asdasd#outlook.com",
"roles": [
{
"id": 1,
"name": "ROLE_USER",
"accessList": [
{
"id_access": 1,
"id_role": {
"id_role": 1,
"name": "ROLE_USER",
"authority": "ROLE_USER"
},
"id_program": {
"id_program": 1,
"code_program": "TEST",
"name": "test"
},
"id_view": {
"id_view": 1,
"code_view": "TEST",
"name": "test"
},
"menuYesNo": true,
"accessYesNo": true,
"saveYesNo": true,
"editYesNo": true,
"deleteYesNo": true
}
]
}
]
}
}
But it return this:
{
"data": {
"id": 1,
"username": "renato",
"name": "Renato",
"email": "asdasd#outlook.com",
"roles": [
{
"id": 1,
"name": "ROLE_USER",
"accessList": [
{
"id_access": 1,
"id_role": {
"id_role": 1,
"name": "ROLE_USER",
"authority": "ROLE_USER"
},
"id_program": {},
"id_view": {},
"menuYesNo": true,
"accessYesNo": true,
"saveYesNo": true,
"editYesNo": true,
"deleteYesNo": true
}
]
}
]
}
}
Only classes AccessModel and RoleModel have bidirectional relationship, exists a relationship unidirectional between ProgramModel and ViewModel with AccessModel.
OBS: I mapped UserModel to UserDTO using ModelMapper. Exists RoleModel inside a UserDTO. RoleModel and AccessModel have an #JsonManagedReference and #JsonBackReference respectively, but ProgramModel and ViewModel not.
#Data
#Entity
#Table(schema = "`SCH`", name = "`USER`")
public class UserModel implements UserDetails {
private static final long serialVersionUID = -2195101536379303067L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(table = "USER", name="`ID_USER`", nullable = true)
private Long id_user;
#Column(table = "USER", name="`USERNAME`", nullable = true, length = 50)
private String username;
#Column(table = "USER", name="`PASSWORD`", nullable = true, length = 255)
private String password;
#Column(table = "USER", name="`NAME`", length = 255)
private String name;
#Column(table = "USER", name="`EMAIL`", length = 255)
private String email;
#Column(table = "USER", name="`DATE_EXPERED`", nullable = true)
private LocalDate dateExpered;
#Column(table = "USER", name="`ACCOUNT_ACTIVE`", nullable = true)
private Boolean accountAtive;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(schema = "`SCH`", name = "`USER_ROLE`" ,
joinColumns = #JoinColumn(
name = "`CD_USER`", referencedColumnName ="`ID_USER`"
),
inverseJoinColumns = #JoinColumn(
name = "`CD_ROLE`", referencedColumnName = "`ID_ROLE`"
))
#JsonBackReference
private Collection<RoleModel> roles;
//METHODS USERDETAILS
}
#Data
#Entity
#Table(schema = "`SCH`", name = "`ROLE`")
public class RoleModel implements GrantedAuthority {
private static final long serialVersionUID = -1320143054659054908L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(table = "ROLE", name = "`ID_ROLE`", nullable = true)
private Long id_role;
#Column(table = "ROLE", name = "`NAME`", nullable = true, length = 255)
private String name;
#JsonBackReference
#OneToMany(cascade = CascadeType.ALL, mappedBy = "id_role", fetch = FetchType.LAZY)
private List<AccessModel> accessList;
}
#Data
#Entity
#Table(schema = "`SCH`", name = "`ACCESS`")
public class AccessModel implements Serializable {
private static final long serialVersionUID = -5590889002302223720L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(table = "ACCESS", name = "`ID_ACCESS`", nullable = true)
private Long id_access;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "`CD_ROLE`")
#JsonManagedReference
private RoleModel id_role;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "`CD_PROGRAM`")
private ProgramModel id_program;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "`CD_VIEW`")
private ViewModel id_view;
#Column(table = "ACCESS", name = "`MENU_YES_NO`", nullable = true)
private Boolean menuYesNo;
#Column(table = "ACCESS", name = "`ACCESS_YES_NO`", nullable = true)
private Boolean accessYesNo;
#Column(table = "ACCESS", name = "`SAVE_YES_NO`", nullable = true)
private Boolean saveYesNo;
#Column(table = "ACCESS", name = "`EDIT_YES_NO`", nullable = true)
private Boolean editYesNo;
#Column(table = "ACCESS", name = "`DELETE_YES_NO`", nullable = true)
private Boolean deleteYesNo;
}
#Entity
#Table(name = "`PROGRAM`", schema = "`SCH`")
public class ProgramModel implements Serializable {
private static final long serialVersionUID = -726159076909575803L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(table = "PROGRAM", name = "`ID_PROGRAM`", nullable = true)
private Long id_program;
#Column(table = "PROGRAM", name = "`CODE_PROGRAM`", nullable = true)
private String code_program;
#Column(table = "PROGRAM", name = "`NAME`", nullable = true)
private String name;
#Column(table = "PROGRAM", name = "`ACTIVE`", nullable = true)
private Boolean active;
}
#Entity
#Table(name = "`VIEW`", schema = "`SCH`")
public class ViewModel implements Serializable {
private static final long serialVersionUID = 3900486010030569933L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(table = "VIEW", name = "`ID_VIEW`", nullable = true)
private Long id_view;
#Column(table = "VIEW", name = "`CODE_VIEW`", nullable = true)
private String code_view;
#Column(table = "VIEW", name = "`NAME`", nullable = true)
private String name;
#Column(table = "VIEW", name = "`ACTIVE`", nullable = true)
private Boolean active;
}
I forgot to put #Data in ProgramModel and ViewModel.
I'm Working On a Spring Boot Application and I have two Entities AdminUsers And Blogs, These two Entities have OneToMany relationship and I wanted to Return all Blogs after save a blog, as follows
#PostMapping("/add")
#ResponseBody
public List<Blog> addBlog(#RequestBody Blog blog) {
Blog savedBlog = blogService.save(blog);
return blogService.findAllBlogs();
}
The problem I'm facing is tt returns null for the last inserted Blog's AdminUser all the time as follows,
[
{
"id": 30,
"adminid": 1,
"blogcontent": "blog dddcontent",
"blogtitle": "titleaa",
"datetime": "1111-12-31 23:59:59",
"adminUser": {
"adminid": 1,
"adminusername": "admin",
"adminemail": "admin#kongcepts.com",
"adminpassword": "$2a$10$3aVlo8BkGbKQYzMDMDZTi.6dQavPeY8j0yD833ldA4utNAE4SxzpC",
"status": 1,
"attempts": 0,
"resetToken": "$2a$10$6o7N/u4pgwjWya30wueVve9oqPNO6TTLidOg6NincqL5lOvLh03oa"
}
},
{
"id": 31,
"adminid": 1,
"blogcontent": "blog dddcontent",
"blogtitle": "titleaa",
"datetime": "1111-12-31 23:59:59",
"adminUser": null
}
]
But when I hit this endpoint after that
#GetMapping("/get/blogs")
public List<Blog> listAllBlogs() {
return blogService.findAllBlogs();
}
It returns as expected
[
{
"id": 30,
"adminid": 1,
"blogcontent": "blog dddcontent",
"blogtitle": "titleaa",
"datetime": "1111-12-31 23:59:59",
"adminUser": {
"adminid": 1,
"adminusername": "admin",
"adminemail": "admin#kongcepts.com",
"adminpassword": "$2a$10$3aVlo8BkGbKQYzMDMDZTi.6dQavPeY8j0yD833ldA4utNAE4SxzpC",
"status": 1,
"attempts": 0,
"resetToken": "$2a$10$6o7N/u4pgwjWya30wueVve9oqPNO6TTLidOg6NincqL5lOvLh03oa"
}
},
{
"id": 31,
"adminid": 1,
"blogcontent": "blog dddcontent",
"blogtitle": "titleaa",
"datetime": "1111-12-31 23:59:59",
"adminUser": {
"adminid": 1,
"adminusername": "admin",
"adminemail": "admin#kongcepts.com",
"adminpassword": "$2a$10$3aVlo8BkGbKQYzMDMDZTi.6dQavPeY8j0yD833ldA4utNAE4SxzpC",
"status": 1,
"attempts": 0,
"resetToken": "$2a$10$6o7N/u4pgwjWya30wueVve9oqPNO6TTLidOg6NincqL5lOvLh03oa"
}
}
]
Here is my Entity classes for AdminUser and Blogs
Admin User
#Entity
#Table(name = "tbl_admin")
public class AdminUser {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "admin_id")
private Integer adminid;
#Column(name = "admin_username", nullable = false)
private String adminusername;
#Column(name = "admin_email", nullable = false)
private String adminemail;
#Column(name = "admin_password", nullable = false)
private String adminpassword;
#Column(name = "admin_status")
private Integer status = 1;
#Column(name = "admin_attempt")
private Integer attempts = 0;
#Column(name = "admin_reset_token")
private String resetToken;
#OneToMany(mappedBy = "adminUser")
#JsonIgnore
private List<Blog> blog;
and Blog
#Entity
#Table(name = "tbl_blog")
public class Blog {
#Id
#Column(name = "blog_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "admin_id")
private Integer adminid;
#Column(name = "blog_content")
private String blogcontent;
#Column(name = "blog_title")
private String blogtitle;
#Column(name = "blog_datetime")
private String datetime;
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name = "admin_id", updatable = false, insertable = false)
private AdminUser adminUser;
I finally figure it out that, for some reasons it didn't worked previously because i was only giving the value to the join column named adminid #JoinColumn(name = "admin_id", updatable = false, insertable = false), all i wanted to do search the relation entity with
AdminUser addedUser = adminService.findbyid(Integer id);
and added the result to the blog's relational entity(admin property),
so final code ends up with something like this.
#PostMapping("/add")
#ResponseBody
public List<Blog> addBlog(#RequestBody Blog blog) {
AdminUser addedAdmin = adminService.findbyid(blog.getAdminid());
blog.setAdminuser(addedAdmin);
blogService.save(blog);
return blogService.findAllBlogs();
}
Try annotating your save() method in blogService with #Transactional
I have 2 tables email_address and group_email
I want to get a list of email addresses and if it is group also list the emails of group. Here is my hibernate dom object:
#Entity
#Table(name = "email_address")
public class EmailAddressDom {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "email_address_id_seq")
#SequenceGenerator(name = "email_address_id_seq", sequenceName = "email_address_id_seq")
private int id;
#Column(name = "name")
private String name;
#Column(name = "email")
private String email;
#Column(name = "is_group")
private boolean isGroup;
#Column(name = "status")
private boolean status;
// Getters and setters
And here is the implementation how I am getting the list
public List<EmailAddressDom> getEmailAddresses() {
Session session = getCurrentSession();
Criteria criteria = session.createCriteria(EmailAddressDom.class);
List<EmailAddressDom> emailAddresses = criteria.list();
return emailAddresses;
}
And the result is
[
{
"id": 451,
"name": "HS",
"isGroup": true,
"status": true
},
{
"id": 452,
"name": "test4",
"email": "test4#mail.com",
"isGroup": false,
"status": true
},
{
"id": 450,
"name": "test3",
"email": "test3#mail.com",
"isGroup": false,
"status": true
},
{
"id": 402,
"name": "test2",
"email": "test2#mail.com",
"isGroup": false,
"status": true
},
{
"id": 401,
"name": "test1",
"email": "test1#mail.com",
"isGroup": false,
"status": true
}
]
I want to get result like this
[
{
"id":451,
"name":"HS",
"isGroup":true,
"status":true,
"groupEmails":[
{
"id":450,
"name":"test3",
"email":"test3#mail.com",
"isGroup":false,
"status":true
},
{
"id":452,
"name":"test4",
"email":"test4#mail.com",
"isGroup":false,
"status":true
}
]
},
{
"id":402,
"name":"test2",
"email":"test2#mail.com",
"isGroup":false,
"status":true
}
]
Which mapping should I use in EmailAddressDom entity?
Updated accordingly to comments
I have written a simple application mapping following way and it is working fine
#ManyToMany(fetch= FetchType.EAGER, cascade={CascadeType.ALL})
#JoinTable(name="group_email",
joinColumns={#JoinColumn(name="group_id")},
inverseJoinColumns={#JoinColumn(name="email_addr_id")})
private List<EmailAddressDom> groupEmails;
But I have confused setting it in my web application, it throws following exception:
Association has already been visited: AssociationKey(table=group_email, columns={email_addr_id})
What can be the reason?
Either Do Eager loading
#OneToMany(fetch = FetchType.EAGER)
#JoinTable(name = "group_email",
joinColumns = #JoinColumn(name = "email_addr_id", referencedColumnName = "id"),
inverseJoinColumns=#JoinColumn(name="group_id", referencedColumnName="id" ))
private List<EmailAddressDom> emailAddressDoms;
OR
//explicitly join in criteria
public List<EmailAddressDom> getEmailAddresses() {
Session session = getCurrentSession();
Criteria criteria = session.createCriteria(EmailAddressDom.class);
criteria.setFetchMode("emailAddressDoms", fetchMode.JOIN);
List<EmailAddressDom> emailAddresses = criteria.list();
return emailAddresses;
}
To achieve self join, in your EmailAddressDom class add reference to itself like:
#OneToMany(fetch = FetchType.LAZY)
#JoinTable(name = "group_email",
joinColumns = #JoinColumn(name = "email_addr_id", referencedColumnName = "id"),
inverseJoinColumns=#JoinColumn(name="group_id", referencedColumnName="id" ))
private List<EmailAddressDom> emailAddressDoms;
In group_email table you do not require id column as email_addr_id and group_id combination would be unique or do you allow same email more than once in a group?
Update after comment from OP:
To group by email groups, change the mapping like shown below.
#ManyToOne(fetch = FetchType.LAZY)
#JoinTable(name = "group_email",
joinColumns = #JoinColumn(name="group_id", referencedColumnName="id" ),
inverseJoinColumns=#JoinColumn(name = "email_addr_id", referencedColumnName = "id"))
private List<EmailAddressDom> emailAddressDoms;