How can I do the multiply relations in Hibernate? - java

everyone! Sorry but I need some help. My db is looking this way, I try to do same throught the Hibernate in Java.
But I don`t understand how I need to annoted this relations with so many different tables.
It`s a part of my Abiturient table.
#Entity
#Table (name = "abiturient",
uniqueConstraints = {#UniqueConstraint(columnNames = {"id"})})
public class Abiturient {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, unique = true, length = 11)
#ManyToOne
private Long id;
#Column
private Date data_narodjennya;
#Column
private Integer city_village;
It`s a part of my nomer_telefonu table
#Entity
#Table(name = "nomer_telefonu")
public class NomerTelefonu {
#Id
#Column(name = "nomer_tel_id", nullable = false, unique = true, length = 11)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long nomer_tel_id;
#Column(name = "nomer")
private String nomer;
#Column(name = "id")
#OneToMany(fetch = FetchType.LAZY)
private Set<Abiturient> id;
I don`t think that all there is right, `cos every time I try to solve problem I get an error and need other type.

Use #OneToMany bidirectional relation.
#Entity
public class Abiturient {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(mappedBy = "abiturent")
private List<NomerTelefonu> phones = Lists.newArrayList();
}
#Entity
public class NomerTelefonu{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "nomer_tel_id")
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
private Abiturient abiturent;
}
Lists.newArrayList() from guava. This is working mapping. Always use the simplest version to experiment.
what is #JoinColumn and how it is used in Hibernate
You can use this project to play with mappings in the unit tests:
https://github.com/v-ladynev/hibernate-experimental

Related

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 POST error whit third entity relationship

I'm new on Spring, i would like to store relationship between Exam and Question whith this structure:
#Entity
#Data
#EqualsAndHashCode(callSuper = true)
public class Exam extends UriEntity<Integer> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#NotBlank
#Length(min = 1, max = 256)
private String name;
#OneToMany(mappedBy="exam")
private List<ExamQuestion> exams_questions;
#Entity
#Data
#EqualsAndHashCode(callSuper = true)
public class Question extends UriEntity<Integer> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#NotBlank
#Column(unique = true)
private String statement;
#NotBlank
private String answer;
#OneToMany(mappedBy="question")
private List<ExamQuestion> exams_questions;
#Entity
#Data
#EqualsAndHashCode(callSuper = true)
public class ExamQuestion extends UriEntity<Integer> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#ManyToOne
#JoinColumn(name = "question_id")
private Question question;
#ManyToOne
#JoinColumn(name = "exam_id")
private Exam exam;
When i want to store a new ExamQuestion object with POSTMAN
{
"exam": "http://localhost:8080/exams/28",
"question": "http://localhost:8080/questions/17"
}
I get an error 409, and the message:
NULL not allowed for column \"ID\";
Any could help me ?
Thanks in advance.
This might happen because of the #GeneratedValue(strategy = GenerationType.IDENTITY).
Make sure that in your database schema ID column is set to be auto incremented, since GenerationType.IDENTITY uses databases identity column to generate values. Thus if your column is not set to be auto incremented you get this error.

Create relation between tables in JPA

I have main table merchants and second table terminals:
Merchant table:
#Entity
#Table
public class Merchants {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", updatable = false, nullable = false)
private int id;
#Column
private String name;
#Column
private String login;
}
Terminal table:
#Entity
#Table
public class Terminals {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", updatable = false, nullable = false)
private int id;
#Column
private int merchant_id;
#Column
private String mode;
}
I want to set merchant_id into table Terminals. I suppose that many to many will be proper relation. How I can create it?
If you have a Join Table:
On Merchants class:
#ManyToMany
#JoinTable(name="MER_TER", joinColumns=#JoinColumn(name="MERCH_ID", referencedColumnName="id"),
inverseJoinColumns=#JoinColumn(name="TERM_ID", referencedColumnName="id"))
private List<Terminals> terminalsList;
On Terminals class:
#ManyToMany(mappedBy="terminalsList")
private List<Merchants> merchantsList;
Page of reference: link
If you don't have a Join Table, try to look here: https://stackoverflow.com/a/25018992

How to use uniqueConstraint on referenced table column with JPA

How can I include a referenced table column in a unique constraint? I want to create a unique constraint for table Survey for columns toEmail, receipt.receiptSeries and receipt.receiptNum.
See entities below please:
Receipt
#Entity
#Table(name = "RECEIPT")
public class Receipt {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private Long id;
#Column(name = "RECEIPT_SERIES")
private String receiptSeries;
#Column(name = "RECEIPT_NUM")
private String receiptNum;
}
Survey
#Entity
#Table(name = "SURVEY"}
public class Survey {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private Long id;
#ManyToOne(optional = false)
#JoinColumn(name = "RECEIPT_ID")
private Receipt receipt;
#Column(name = "TO_EMAIL")
private String toEmail;
}
I've tried using the approach below with no success:
#Table(name = "SURVEY", uniqueConstraints = {
#UniqueConstraint(columnNames = {"TO_EMAIL", "RECEIPT.RECEIPT_SERIES", "RECEIPT.RECEIPT_NUM"})})
Using a composite primary key with receiptSeries and receiptNum for Receipt is not an option.
Try something like this
#Table(name="notification_status", uniqueConstraints=
arrayOf(UniqueConstraint(columnNames= arrayOf("external_user_id",
"external_organization_id",
"notification_id"))))

Joining with cross-reference table in hibernate and spring

I use hibernate and spring-data. There are two tables with many-to-many relationship.
#Entity
#Table(name = "FirstEntity")
public class FirstEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "first_entity_id")
private Long id;
#Column(name = "first_entiry_name")
private String name;
/* getters and setters are below*/
}
#Entity
#Table(name = "SecondEntity")
public class SecondEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "second_entity_id")
private Long id;
#Column(name = "second_entiry_name")
private String name;
#Column(name = "second_entiry_desc")
private String description;
/* getters and setters are below*/
}
And entity for cross-reference table.
#Entity
#Table(name = "FirstSecondEntity")
public class FirstSecondEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "first_second_entity_id")
private Long id;
#Column(name = "first_entity_id")
private Long firstEntityId;
#Column(name = "second_entity_id")
private Long secondEntityId;
/* getters and setters are below*/
}
I need SELECT like this
SELECT FirstEntity.name, SecondEntity.name, SecondEntity.description FROM SecondEntity INNER JOIN FirstSecondEntity ON SecondEntity.id = FirstSecondEntity.secondEntityId INNER JOIN User ON FirstEntity.id = FirstSecondEntity.firstEntityId
i.e. I need all records from cross-reference table where instead of ids there is actual info from entities.
Inserting this query into #Query annotation in my CrudRepository-extended class doesn't work because of
ERROR [main][org.hibernate.hql.internal.ast.ErrorCounter] Path expected for join!
So I need your help.
Your join table is all screwed up. In this case, you actually don't even need the join table as a hibernate mapping:
In Second Entity add the following list:
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "FirstSecondEntity",
joinColumns = {
#JoinColumn(name = "first_entity_id",
nullable = false,
updatable = false) },
inverseJoinColumns = {
#JoinColumn(name = "second_entity_id",
nullable = false,
updatable = false) },
)
private List<FirstEntity> firstEntities;
In FirstEntity add the following list:
#ManyToMany(fetch = FetchType.LAZY,
mappedBy = "firstEntities")
private List<SecondEntity> secondEntities;

Categories

Resources