Can I use a single entity for multiple tables? - java

I have multiple tables in database with exactly same columns and signature.
All the tables are created based on year like all the data for 2020 is in one table and for 2021 it's in other table.
Is it possible to use the a single entity for multiple tables?

Yes, this is possible. You can specify your tables name and prefix them in a single entity class.
#Entity#Table(name="student")#SecondaryTables({
#SecondaryTable(name="name", pkJoinColumns={
#PrimaryKeyJoinColumn(name="id", referencedColumnName="student_id") }),
#SecondaryTable(name="address", pkJoinColumns={
#PrimaryKeyJoinColumn(name="id", referencedColumnName="student_id") })})
public class Student implements Serializable {
#Id
#Column(name="student_id")
private int studentId;
#Column(table="name")
private String name;
#Column(table="address")
private String address;
public Student(){}
public Student(int studentId){
this.studentId=studentId;
}
//getters and setters
}
You can use this piece of code.

Related

How to do one to many relationships in JDBC?

I have class two classes
i want to perform one to many relationship
public class Teacher {
private int id;
private String name;
private List<Class> classes;
}
public class Class {
private int id;
private String className;
}
I need to retrieve data and print data from the database
Teacher Classes
Kumar A1,B3,B4
Deepa A1,A2,C1
Alex B2,D1,D2
I don't Know how to retrive one to many relationship data in JDBC
please suggest me what should i do?
I do know about 2 ways to do it with jdbc
You need to select all teachers first, then for each teacher select his classes.
select * from teacher
then map results to your teacher class then on java side make a for each loop and fetch class by teacher_id for each teacher
select * from class where teacher_id = :teacher_id
You can select all teachers and classes like that:
select * from teacher t
left join class c on c.teacher_id = t.teacher_id
but you will get duplicate data of teacher becouse in each row you will fetch data for teacher also and you will need to organize it on Java side.
So I've been working recently with Spring JDBC myself. This is something similar with what I've come up with by reading here and there. I really appreciate the simplicity of JDBC combined with the domain driven approach:
public class Teacher {
#Id private int id;
private String name;
#MappedCollection(idColumn = "teacher_id", keyColumn = "teacher_key")
private List<Class> classes;
//setters and getters
}
public class Class {
private int id;
private String className;
//setters and getters
}
Then you need to create the repository interface by extending CrudRepository from Spring JDBC, you don't need to create an extra repository to e.g. save Class data through Teacher :
interface TeacherRepository extends CrudRepository<Teacher, Integer> {}
The TeacherRepository will have the typical CRUD methods that allow you to read or write data from/to the database.
The sql code (this is postgres like, change to your specific dialect) would be something like this:
create table teachers(
id serial primary key,
name text
)
create table classes(
id serial primary key,
class_name text,
teacher_id int references teachers(id),
teacher_key int
)
Where the teacher_key column is used to return an ordered list of classes. If you don't care about the classes ordering you can just return a set instead of a list:
public class Teacher {
#Id private int id;
private String name;
#MappedCollection(idColumn = "teacher_id")
private Set<Class> classes;
//setters and getters
}
public class Class {
private int id;
private String className;
//setters and getters
}
the sql code:
create table teachers(
id serial primary key,
name text
)
create table classes(
id serial primary key,
class_name text,
teacher_id int references teachers(id)
)
Here are my sources:
https://www.youtube.com/watch?v=ccxBXDAPdmo
https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates
https://lumberjackdev.com/spring-data-jdbc
https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#jdbc.repositories

List denormalization with morphia

Suppose i have two morphia entities: Person and Team which are look like this
#Entity
public class Person {
private String name;
private String login;
private String mail;
private List<Team> teams;
}
#Entity
public class Team {
private String name;
private String description;
private List<Person> members;
//some more fields
}
I want map this model into Mongodb database like this
Users collection
{
name:"someName",
login:"somelogin",
mail:"some#mail.com",
teams: [
{id:"teamId", name:"TeamName"} //only specific fields fron Team Entity
{id:"anotherTeamId", name:"AnotherTeamName"}
]
}
Teams collection
{
id:"teamId",
name:"TeamName",
description:"Very strong team",
members: [id:"aaa", name: "someName"] //only specific fields fron User Entity
//some other fields
}
{
id:"anotherTeamId",
name:"AnotherTeamName",
description:"Brave new team",
members: [id:"aaa", name: "someName"] //only specific fields fron User Entity
//some other fields
}
So, I want denormolize only specific fields (only name for example) from Team document into User's teams field.
I don't understand Can I use morphia (or some other odm) for this case? Which annotations I should use in my Entities?
It seems that #Reference annotation is not allowed with List<> fields.
I think, i should create inner class PersonTeam, which will contain Team's name and id, and use it in Person class
#Entity
public class Person {
private String name;
private String login;
private String mail;
private List<PersonTeam> teams;
}
public class PersonTeam {
private String teamId;
private String teamName;
}
Is this a good way to solve my problem? thank you!
That's about the only way to do it with morphia at least. You might consider using #Reference on those fields and only storing the IDs. That'd help if your concern is saving space.

Implement one-to-one relationship in java

I came up with an example demonstrating the one-to-one relationship between Employee class and EmployeeDetail class:
public class Employee {
private Long empId;
private String name;
private EmployeeDetail employeeDetail;
//gettter and setter
}
public class EmployeeDetail{
private Long empDetailsId;
private String empFullName;
private String empMailId;
private Employee employee;
//getter and setter..
}
In the Employee class, there's an EmployeeDetail field, and in EmployeeDetail class, there's an Employee field. I understand that as each Employee has its own EmployeeDetail and each EmployeeDetail belongs to only one Employee, but there're 2 points that confuse me:
What if two or more Employees have the same EmployeeDetail (and vice versa)? Is there any way to handle this in Java code or I can only do that in a relational database management system?
In SQL, foreign keys (IDs) represent the relationship between two tables, but in the above example, they use class objects instead. Please help me explain that
In an one-to-one relation, an EmployeeDetail can only belong to one Employee. If an EmployeeDetail should be able to belong to multiple Employees you will need a Many-to-one relationship (Many Employees to one Employee Detail).
The reason the foreign keys are noted by class objects is that this is most likely a Hibernate example, which uses Java Objects for database management. (Even if it misses some annotation for a clear Hibernate example)
Here you can find an example about Hibernate and database relations
look at this ex :
#Entity
#Table(name="d_agent_auth")
public class AgentAuth implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int idAuth;
#NotNull
private String password;
private Date dateCreation;
#OneToOne
#JoinColumn(name="code_agent")
private Agent agent;
public AgentAuth() {
super();
}
}
there is two way a navigable one sens and two sens that's means in the agent class you will not find a key reference agentAuth or two sens means that's in the agent you will find it :
#Entity
#Table(name="d_agent")
public class Agent implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String codeAgent;
#ManyToMany(mappedBy="DAgents", cascade=CascadeType.MERGE)
private List<Profil> profil;
#OneToMany(mappedBy="DAgent")
private List<SuiviDossier> DSuiviDossiers;
#OneToMany(mappedBy="DAgent")
private List<SuiviLot> suiviLots;
#OneToMany(mappedBy="agent")
private List<Affectation> affecter;
public Agent() {
super();
}
}

How to map one class with multiple tables in Hibernate/javax.persistance?

I want to use one class to map three tables. I know javax.persistance provides the #SecondaryTable annotation to map two tables to one class.
Below is the code, where I have used #SecondaryTable. It allows me to define only one secondary table. But I need 3 tables to be used by the same class.
#Entity
#Table(name = "table1")
#SecondaryTable(name="table2")
public class TableConfig
implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#Column(name = "mac", table= "table1")
private String uniqueIdentifier;
I want to use one class to map three tables, From what I know is that javax.persistance provides #SecondaryTable annotation to map two tables to one class
use #SecondaryTables to map more than one table.
You can map a single entity bean to several tables using the #SecondaryTables class level annotations. To express that a column is in a particular table, use the table parameter of #Column or #JoinColumn.
for example there is 3 entity's namely: Name , Address & Student:
Name entity will look like:
#Entity
#Table(name="name")
public class Name implements Serializable {
#Id
#Column(name="id")
private int id;
#Column(name="name")
private String name;
public Name(){}
public Name(int id,String name){
this.id=id;
this.name=name;
}
//getters and setters
}
Address entity will look like:
#Entity
#Table(name="address")
public class Address implements Serializable {
#Id
#Column(name="id")
private int id;
#Column(name="address")
private String address;
public Address(){}
public Address(int id, String address) {
super();
this.id = id;
this.address = address;
}
//getters and setters
}
Student entity will look like:
#Entity
#Table(name="student")
#SecondaryTables({
#SecondaryTable(name="name", pkJoinColumns={
#PrimaryKeyJoinColumn(name="id", referencedColumnName="student_id") }),
#SecondaryTable(name="address", pkJoinColumns={
#PrimaryKeyJoinColumn(name="id", referencedColumnName="student_id") })
})
public class Student implements Serializable {
#Id
#Column(name="student_id")
private int studentId;
#Column(table="name")
private String name;
#Column(table="address")
private String address;
public Student(){}
public Student(int studentId){
this.studentId=studentId;
}
//getters and setters
}
Store like:
Student s= new Student(1);
session.save(s);
Name n=new Name(s.getStudentId(),"Bilal Hasan");
session.save(n);
Address address = new Address(s.getStudentId(), "India");
session.save(address);
Student ob = (Student)session.get(Student.class, s.getStudentId());
System.out.println(ob.getStudentId());
System.out.println(ob.getName());
System.out.println(ob.getAddress());
ouput:
1
Bilal Hasan
India
you can define one class like below :
#Entity
#Table(name="table1")
#SecondaryTables({
#SecondaryTable(name="table2", pkColumnJoins={#PrimaryKeyJoinColumn(name = "id")}),
#SecondaryTable(name="table3", pkColumnJoins={#PrimaryKeyJoinColumn(name = "id")})
})
public class TestEntity {
#Id
#GeneratedValue
private int id;
private String field1;
#Column(name="column2", table="table2")
private String field2;
#Column(name="column3", table="table3")
private String field3;
getter and setter...
}
In your DB, should has three table, and all of them should has the same primary key "id".
then, use can test like this:
TestEntity test = new TestEntity();
test.setField1("field1");
test.setField2("field2");
test.setField3("field3");
em.merge(test);
after test, in your DB, you will find one record in each table:
table1:
1, field1
table2:
1, field2
table3:
1, field3
all of them will share the primary key value. Hope this will help you.
In Hibernate mapping file you can specify the entity-name mapping with virtual name along with polymorphism="explicit" and class name would be physical class name. Like that you may do multiple mappings. While loading the object use entityname (virtual name).

How to store some of the entity's values in another table using hibernate?

is there a simple way to persist some of the fields in another class and table using hibernate.
For example, I have a Person class with name, surname, email, address1, address2, city, country fields. I want my classes to be:
public class Person
{
private String name;
private String surname;
private String email;
private Address address;
// ..
}
public class Address
{
private Person person; // to whom this belongs
private String address1;
private String address2;
private String city;
private String country;
// ..
}
and I want to store Address in another table. What is the best way to achieve this?
Edit: I am using annotations. It does not have to be the way I described, I am looking for best practices.
Edit 2: What will be the Id of Address?
PS. If there is a way to make Address immutable (to use as a value object) that is even better, or maybe not because I thought everything from wrong perspective :)
map Address as an entity and add a primary key (an auto-generated id)
map the relation between Person and Address as one-to-one (#OneToOne on each field)
With Hibernate 3.5 it is possible to define foreign generators (aka. JPA mapping), details are here.
It is pretty straight forward Person should implement Serializable then #Id annotation is added to person.
#Entity
#AccessType(value = "field")
#Table(name = "addresses")
public class Address
{
#Id
#OneToOne
#JoinColumn(name = "person_id")
private Person person;
// ...
}
There is an alternative but I really like the first one:
#Entity
#AccessType(value = "field")
#Table(name = "addresses")
public class Address
{
#Id
private int personId;
#MapsId
#OneToOne
#JoinColumn(name = "person_id")
private Person person;
// ...
}

Categories

Resources