I have two classes Student and Address.
Student{
stuid,
stuName,
}
Address{
street,
city,
stuid;//foriegn key Ref with Studnet
}
Can any one help me to map these two classes using hibernate??
You should learn what is OneToOne mapping in hibernate firstly.
Secondly if I would want to design then I would have address_id as foreign key in Student table and not student id.
//Table name will be taken as Student as you are not specifying it using #Table annotation
Student class
#Entity
public class Student{
#Id
#Column("stuid")
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column("stuName")
private String name;
//setters and getters
}
Address class
#Entity
public class Address{
#Id
#Column("add_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column("street")
private String street;
#Column("city")
private String city;
#OneToOne(cascade={CascadeType.SAVE,CascadeType.MERGE})
#JoinColumn(name="stuid")
private Student student
//setters and getters
}
Suppose if a Student can have multiple Address entities then you need to have one-to-many relationship between Student and Address classes. A student should know what addresses they belong to and also as you need to save the student id in address table then the relationship becomes bi-directional.
The entities looks like this:
Student.java
#Entity
#Table(name = "student_tbl") // Optional, By default table name is student, if you want to give different name then use this line.
public class Student1 {
#Id
#GeneratedValue
private int stuid;
private String stuName;
#OneToMany(mappedBy = "student")
private List<Address> address = new ArrayList<Address>();
// Setters & Getters
}
Address.java
#Entity
#Table(name = "address_tbl")
public class Address {
#Id
#GeneratedValue
private int addressId;
private String street;
private String city;
#ManyToOne
#JoinColumn(name="stuid")
private Student1 student;
// Setters & Getters
}
Related
My tables look like this:
School
-------
school_id (pk)
...
Student
school_id (pk) (fk)
student_id (pk)
...
So using JPA (Hibernate), I tried something like this.
#Entity
#Table("SCHOOL")
public School {
#Column(name = "SCHOOL_ID")
private String schoolId;
#OneToMany
private List<Student> students;
}
#Entity
#Table("STUDENT")
public Student {
#EmbeddedId
private StudentPK studentPK;
#ManyToOne
#JoinColumn(name = "SCHOOL_ID")
private School school;
}
#Embeddable
public StudentPK implements Serializable {
#Column(name = "SCHOOL_ID")
private String schoolId;
#Column(name = "STUDENT_ID"
private String studentId;
}
When I do this, I frequently get an error that says that the foreign key constraint is being violated on runtime. I suspect that JPA is trying to generate a new foreign key called "SCHOOL_ID" instead of using the existing column from my composite key, but I'm not sure how to force it to use the existing column.
These relationships should be mapped a bit differently:
#Entity
#Table("SCHOOL")
public School {
#Column(name = "SCHOOL_ID")
private String schoolId;
#OneToMany(mappedBy="school")
private List<Student> students;
}
#Entity
#Table("STUDENT")
public Student {
#EmbeddedId
private StudentPK studentPK;
#ManyToOne
#MapsId("schoolId")
private School school;
}
#Embeddable
public StudentPK implements Serializable {
#Column(name = "SCHOOL_ID")
private String schoolId;
#Column(name = "STUDENT_ID"
private String studentId;
}
Note the #OneToMany.mappedBy attribute on School.students and #MapsId annotation on Student.school.
Derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.
I want to do :
create table user (
id bigint primary key auto_increment,
firstname varchar(128),
lastname varchar(128),
street varchar(128),
zipcode mediumint,
city varchar(128)
)
then :
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstname;
private String lastname;
private Address address; // Here I want an Address rather than street, zip, and city directly inside User
...
}
and :
public class Address {
private String street;
private Integer zipcode;
private String city;
...
}
(that is an example)
How to do that with Hibernate ? #OneToOne ? The problem seems simple and since I can't find the solution around here, it must be obvious.
First, annotate your Address class with #Embeddable:
#Embeddable
public class Address {
/*class definition here*/
...
}
And then update your user class in this way:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstname;
private String lastname;
#Embedded
private Address address;
...
}
That's it. If you want a more complex example look here. Just pay attention to model classes definition, it makes no difference if you are using Spring Boot or not as long as you handle your database with JPA.
You can associate entities through a one-to-one relationship using #OneToOne annotation.
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Address address;
#OneToOne(cascade = CascadeType.ALL)
#PrimaryKeyJoinColumn
public Address getAddress()
{
return address;
}
}
Reference:
https://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-association
I have two tables with one to one relationship b/w student and address table
Student
student_id
name
Address
address_id
student_id(foreign key to student_id in student table)
...
Here is the relevant entity section
#Entity
#Table(name = "STUDENT")
public class Student {
#Id
#GeneratedValue
#Column(name = "STUDENT_ID")
private long id;
#OneToOne
private Address address;
}
#Entity
#Table(name = "ADDRESS")
public class Address {
#Id
#GeneratedValue
#Column(name = "ADDRESS_ID")
private long id;
private long student_id;
}
I want to keep the foreign key i.e. student_id(foreign key to id in student table) under address table as shown in table structure at top but
want to keep the undirectional association of private Address address under student entity. I am not sure how to achieve it ?
what I tried is this
#Entity
#Table(name = "STUDENT")
public class Student {
#Id
#GeneratedValue
#Column(name = "STUDENT_ID")
private long id;
#OneToOne(mappedBy ="student_id")
private Address address;
}
#Entity
#Table(name = "ADDRESS")
public class Address {
#Id
#GeneratedValue
#Column(name = "ADDRESS_ID")
private long id;
#OneToOne
#JoinColumn(name="student_id")
private long student_id;
}
But it gives below exception
#OneToOne or #ManyToOne on Address.student_id references an unknown entity: int
at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:107)
at org.hibernate.cfg.Configuration.processEndOfQueue(Configuration.java:1580)
at
It works as soon as I make association bidirectional with
private Student student_id instead of private long student_id
So in a way Hibernate forcing me to make association bidirectional when foreign key exist in supplementary table(in this case address table)
My requirement is to have a list of classes and students of each class. Each students must be in zero or at most one class. My code is as following, but in database, each student can be in many classes. How to keep each student in zero to one and only one class?
Student item table is as following
StudentItem
id student_id code
1 1 233
2 5 453
3 1 567
4 6 565
Entities
#Entity
public class MyClass{
#Id
#GeneratedValue
private long id;
#OneToMany( cascade = CascadeType.ALL)
#LazyCollection(LazyCollectionOption.FALSE)
private List<StudentItem> students;
private String season;
...
}
#Entity
public class StudentItem{
#Id
#GeneratedValue
private long id;
#OneToOne
private Student student;
private String code;
...
}
#Entity
public class Student{
#Id
#GeneratedValue
private long id;
private String fname;
private String lname;
....
}
It seems to me that it's a many-to-one relationship between MyClass and StudentItem, with MyClass owning the relationship between them. Further, it may be simpler and more straightforward to use a join table between these two entities; this way, you don't run the risk of creating more than one MyClass entry in your database.
Think of it like this: what is the actual effective relationship between a class and a student? From your description, one class may hold many students, but any given student may only be in one class.
Here's a rough-hand example from memory on how to create it. I'll assume that there is a joining table between StudentItem and MyClass called classroom_students, with columns student_item_id and class_id.
#Entity
public class MyClass {
#Id
#GeneratedValue
private Integer id;
#OneToMany
#JoinTable(name = "classroom_students",
joinColumns = #JoinColumn(name = "student_item_id"),
inverseJoinColumns = #JoinColumn(name = "class_id"))
private List<MyClass> students;
// getters and setters for entity
}
#Entity
public class StudentItem {
#Id
#GeneratedValue
private Integer id;
#OneToOne(mappedBy = "student_id")
private Student student;
#ManyToOne(targetEntity = MyClass.class,
mappedBy = "students")
private MyClass myClass;
}
Database
*user_account*
id (PK)
email
password
*user_detail*
id(PK)(FK)
name
city
Entities
#Table(name="user_detail")
public class UserDetail implementsSerializable{
#Id private Integer id;
...
#OneToOne
#JoinColumn(name="id")
private UserAccount userAccount;
}
#Table(name="user_account")
public class UserAccount implementsSerializable{
#Id private Integer id;
#OneToOne(mappedBy="userAccount")
private UserDetail userDetails;
}
Error
Exception Description: Multiple writable mappings exist for the field [user_detail.ID]. Only one may be defined as writable, all others must be specified read-only.
If the ID in UserAccount is both a primary key and a foreign key, then you should declare it as a single field and map it appropriately. Like this:
#Entity
public class UserAccount implements Serializable {
#Id
#OneToOne(mappedBy="userAccount")
private UserDetail userDetails;
}
Or else using #MapsId.
However, i suspect that what you really want is a single class spread over two tables:
#Entity
#Table(name = "user_account")
#SecondaryTable(name = "user_detail")
public class User implements Serializable {
#Id
private int id;
private String email;
private String password;
#Column(table = "user_detail")
private String name;
#Column(table = "user_detail")
private String city;
}
You cannot have both #Id private Integer id; and #JoinColumn(name="id"), you must remove one of them: I doubt that you really need a primary key in the details, so just remove the #Id line from there.