How to map a String to an application object in Mapstruct - java

Let's say I have this UserRole class.
It contains the roles of each user.
#Entity
#Table(name="user_roles")
public class UserRole implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column
private long userRoleId;
#ManyToOne
#JoinColumn(name = "user_id", foreignKey = #ForeignKey(name = "users_fk"), nullable=false)
private User user;
#ManyToOne
#JoinColumn(name = "role_id", foreignKey = #ForeignKey(name = "roles_fk"), nullable=false)
private Role role;
...
}
Now I want to have a DTO class with just userName and role that will map to the original class.
public class UserRoleRequestDTO {
private String userName;
private String role;
...
}
How do I create a mapper for that?
#Mapper
public interface UserRoleMapper {
#Mapping(//** What goes here? **//)
UserRole UserRoleRequestDTOtoUserRole(UserRoleRequestDTO userRoleRequestDTO);
}

Related

Enum values are not saved in the database(PostgreSql)

The issue is that the enum values are not being saved in the database, so whenever I register new user it returns user with 0 role size even though I have all the right configurations, so came to the root cause which is enum values of ERole not being saved in the database and the Role table is empty.
ERole enum:
public enum ERole {
ROLE_USER,
ROLE_MODERATOR,
ROLE_ADMIN
}
Role entity:
#EqualsAndHashCode
#NoArgsConstructor
#Getter
#Setter
#Entity
#Table(name = "roles")
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Enumerated(EnumType.STRING)
#Column(length = 20)
private ERole role;
#ManyToMany(mappedBy="roles")
private List<User> users = new ArrayList<>();
public Role(ERole role) {
this.role = role;
}
}
User entity:
#Getter
#Setter
#NoArgsConstructor
#EqualsAndHashCode
#Entity
#Table(name = "users",
uniqueConstraints = {
#UniqueConstraint(columnNames = "name"),
})
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String pass;
#JsonIgnoreProperties("users")
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "user_roles",
joinColumns = { #JoinColumn(name = "user_id") },
inverseJoinColumns = { #JoinColumn(name = "role_id") })
private List<Role> roles = new ArrayList<>();
public User(String name, String pass) {
this.name = name;
this.pass = pass;
}
}
As you see below in the diagram Role entity has the role column with ERole type
I have seen the oter similar threads where it is suggested to use the #Enumerated(EnumType.STRING) which I've been using in the first place.

How to map master detail on hibernate?

I can not change the db schema and this is what I got so far:
public class User{
#Id
private String userId;
#OneToMany
#JoinTable(
name = "user_invoice",
joinColumns = #JoinColumn(name="user_id"),
inverseJoinColumns = #JoinColumn(name = "invoice_id")
)
private List<InvoiceItem> invoiceItems;
}
public class InvoiceItem{
#Id
private String invoiceId;
private String invoiceItemId;
}
This configuration does not allow invoice_id to be duplicated on invoice_item table(it should since I can have multiple items on a given invoice)
If I make invoice_item_id composite pk I would need to add an extra column on user_invoice table which I can not.
How can I map this?
You could split up the many-to-many association into two one-to-many associations and an entity for the join table. You can map it like this:
public class User{
#Id
private String userId;
#OneToMany(mappedBy = "user")
private List<Invoice> invoices;
}
#Table(name = "user_invoice")
public class Invoice{
#Id
#ManyToOne(fetch = LAZY)
#JoinColumn(name="user_id")
private User user;
#Id
private String invoiceId;
#OneToMany(mappedBy = "invoice")
private List<InvoiceItem> invoiceItems;
}
public class InvoiceItem{
#Id
#ManyToOne(fetch = LAZY)
private Invoice invoice;
#Id
private String invoiceItemId;
}

Why JpaRepository<User, Long> returns null value

I have a Spring Boot project, in which I have problem with JpaRepository<User,Long>.
I defined following interface
public interface UserDAO extends JpaRepository<User, Long> {
User findByEmail(String email);
}
which was implemented in UserServiceImpl
#Override
public User findByEmail(String email) {
return userDAO.findByEmail(email);
}
and I need it in UserDetailsServiceImpl but next line
User user = userDAO.findByEmail(email);
returns null.
My model classes:
User
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#Column(name = "email")
private String email;
#Column(name = "login")
private String login;
#Column(name = "password")
private String password;
#ManyToMany
#JoinTable(name = "user_roles",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles;
#Transient
private String confirmPassword;
//getters-setters
}
Role
#Entity
#Table(name = "roles")
public class Role implements GrantedAuthority {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "name")
private String name;
#ManyToMany(mappedBy = "roles")
private Set<User> users;
What can I do?
You need to follow JavaBean specification for entity(you need to have default contrucor and getters and setters in User and Role)
Try to use the annotations on the getter, not the fields.

How to add movie_id and user_id in "movie_added_by" table

I have already a user model.
Now I have created a movie model, my requirement is that whenever any existing user is going to add any movie, at that time user_id and movie_id will be store in the movie_added_by table.
Here user model needs to map one to many to movie_added_by and similarly, the movie will be mapped to movie_added_by.
For better understanding, you can refer to the DB diagram.
I really don't know how can I do by using hibernate annotation
The user model is like this:
#Getter
#Setter
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id", unique = true, nullable = false)
private Integer user_id;
private String name;
}
The movie model is like this:
#Getter
#Setter
public class Movie implements Serializable
{
private static final long serialVersionUID = -6790693372846798580L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "movie_id", unique = true, nullable = false)
private Integer movie_id;
private String movie_name;
}
You probably want to create a #ManyToMany relationship between the entities. There are 2 ways of doing it (with intermediary table created explicitly or by Hibernate.
In simple approach your entities would look as following:
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id", unique = true, nullable = false)
private Integer user_id;
private String name;
#ManyToMany(cascade = CascadeType.Persist)
#JoinTable(name="user_movie",
joinColumns = {#JoinColumn(name="user_id")},
inverseJoinColumns = {#JoinColumn(name="movie_id)})
private Set<Movie> movies = new HashSet<>();
}
public class Movie implements Serializable
{
private static final long serialVersionUID = -6790693372846798580L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "movie_id", unique = true, nullable = false)
private Integer movie_id;
private String movie_name;
#ManyToMany(cascade = CascadeType.Persist, mappedBy = "movies" //field from the user class responsible for mapping)
private Set<User> users = new HashSet<>()
}
So basically here you tell Hibernate to create an intermediary table and keep there correlated id's of those 2 entities. Couple of other notes here:
a) you might want to change the id variable type from Integer to Long in case your entities grow;
b) If you have annotated a column with #Id, you don't have to use unique=true and nullable = false in the column annotation;
c) remember about implementing no-args constructor;
d) remember to exclude relationship fileds from the equals(), hashCode() and the toString() methods;
There is another way, where you explicitly create a model for the table keeping relationships. This might become handy, when it turns out that You need to keep more data in the 'relationship table'. In that case, Your entities would look as following:
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id", unique = true, nullable = false)
private Integer user_id;
private String name;
#OnetToMany(cascade = CascadeType.PERSIST, mappedBy = "user")
private Set<AddedMovie> addedMovies = new HashSet<>()
}
public class Movie implements Serializable
{
private static final long serialVersionUID = -6790693372846798580L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "movie_id", unique = true, nullable = false)
private Integer movie_id;
private String movie_name;
#OneToMany(cascade = CascadeType.PERSIST, mappedBy = "movie")
private Set<AddedMovie> moviesAddedByUser = new HashSet<>();
}
#Data
#AllArgsConstructor
#NoArgsConstructor
#Builder
#Entity
public class AddedMovie{
#Id
#GeneratedValue
private Long id;
#ManyToOne(cascade = CascadeType.PERSIST)
#JoinColumn(name = "user_id")
private User user;
#ManyToOne(cascade = CascadeType.PERSIST)
#JoinColumn(name = "movie_id")
private Movie movie;
// sine this entity has now its own lifecycle, you can add more fields here
private Integer rating;
private LocalDateTime movieAddedOn;
}

Spring : create object with id from another table

I created objects User and Message, and now I want, that message's id will be associated with the user id. How can I do it with annotations or with something else?
Table User
Table Messge
Message class
#Entity
public class Message {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String text;
private String tag;
}
User class
#Entity
#Table(name = "usr")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String username;
private String password;
private boolean active;
#ElementCollection(targetClass = Role.class , fetch = FetchType.LAZY)
#CollectionTable(name = "user_role" , joinColumns = #JoinColumn(name = "user_id"))
#Enumerated(EnumType.STRING)
private Set<Role> roles;
}
you can try this:
Message class:
#Entity
public class Message {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String text;
private String tag;
#ManyToOne
#JoinColumn(name = "user_id")
private User userId;
}
user class:
#Entity
#Table(name = "usr")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String username;
private String password;
private boolean active;
#ElementCollection(targetClass = Role.class , fetch = FetchType.LAZY)
#CollectionTable(name = "user_role" , joinColumns = #JoinColumn(name = "user_id"))
#Enumerated(EnumType.STRING)
private Set<Role> roles;
#OneToMany(mappedBy = "user")
#JsonBackReference
private set<Message> messages;
}

Categories

Resources