How to do one to many relationships in JDBC? - java

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

Related

Hibernate/JPA - How to find all records, that match the pairs of given parameters, when they are not the primary key?

Consider a class Car
#Entity
class Car{
#Id
private UUID id; // primary key- this is the only thing that can't change.
private String name;
private String brand;
private string model;
#Data
public static class Key{
private String brand;
private String model;
}
}
There is a List.of(new Key("brand1","model1"), new Key("brand2","model2")).
How is it possible to find all those given cars by those keys?
Is it doable with only JPA methods? Do I need to write native query? Can I modify something (besides primary key) in order to do it correctly?
I went to the direction of #EmbeddedId and then use the JPA method findAllById(Collection ..) which would be the naïve solution, but it's impossible since it must be the primary key in order to work.

Can I use a single entity for multiple tables?

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.

Hibernate many-to-many set primary/foreign keys in thrid table

I have 3 java classes, two entites and the third is relationship between them. I want to map them in hbm.xml, but I don't know how, I can't find any example on internet
public class Product {
private String _description;
private String _name;
private double _price;
private Long _productId;
private int _quantity;
public class Order {
private Long _orderId;
private List<OrderProduct> _productList;
private User _user;
public class OrderProduct {
private Order _order;
private Product _product;
How to map this in xml, to this thrid class "OrderProduct" stores only order and product as primary and foreign keys.
Thanks in advice
There is no need for OrderProduct entity. You can define the mapping in the hbm Itself. Please see the below link to understand how its done.
https://www.mkyong.com/hibernate/hibernate-many-to-many-relationship-example/

hibernet one to many on web

I am completely new in Hibernate ORM world, recently reading mapping specially one-to-many relation. But i am facing some problem to understand.
I am using this link to understand hibernate relation.
https://dzone.com/tutorials/java/hibernate/hibernate-example/hibernate-mapping-one-to-many-using-annotations-1.html
please have a look the code.
public class Student {
private long studentId;
private String studentName;
private Set<Phone> studentPhoneNumbers
//setter getter
}
public class Phone {
private long phoneId;
private String phoneType;
private String phoneNumber;
//setter getter
}
i understand it.
confusion is here.
Set<Phone> phoneNumbers = new HashSet<Phone>();
phoneNumbers.add(new Phone("house","32354353"));
phoneNumbers.add(new Phone("mobile","9889343423"));
Student student = new Student("Eswar", phoneNumbers);
session.save(student);
Does this only one code session.save(student), store value in both table ? if no then why we didn't write code to save phoneNumbers like session.save(phoneNumbers).
Once this above code is executed then the value will be stored in both table or object(STUDENT and PHONE) right ?. I think each time we execute this code, this code insert value in both table. i don't like it. i want value should be store on only second table(PHONE).
So how will i store value in only PHONE object ?
or how will we implement this relation where user will select STUDENT through combobox and fill value in PHONE object through simple textboxes. then finally save it.like product/category.
3.please help or suggest some good tutorial where hibernate is implemented (specially one-to-many and many to many relation) in web application. i have seen many tutorial but all these are implemented through main method.
sorry for the poor English
thanks.
Yes it should save both student and phone number in their own table. If you annotate the right way. Student should be something like this:
#Entity
#Table(name = "student")
public class Student {
#id
#GeneratedValue
private long studentId;
#column(name = "studentName")
private String studentName;
#OneToMany
private Set<Phone> studentPhoneNumbers
//setter getter
}
public class Phone {
private long phoneId;
private String phoneType;
private String phoneNumber;
//setter getter
}
Then there is also some configuration to do. I'd advice you to read this tutorial: https://www.tutorialspoint.com/hibernate/index.htm
In the case of your code it doesn't much. But if you configure hibernate the right way you can decide in which table/column a value should be saved
Hibernate tutorial - Tutorials point

Hibernate Inheritance mapping issue

So, after several attempts of trying and trying to make this work the way I want, and of course checking different guide, I now come to you guys.
My program is designed to work like this:
persona (the father object)
-persona_cuil (pk on DB, generated by user)
empleado (persona's son)
-legajo_id (pk on DB, generated by program NOT DB (couldnt make that work either))
-persona_cuil (FK from persona)
empvarios (empleado's son)
-legajo_id (PK and FK from empleado)
Now, the database is mapped that way, and it works just fine, the problem seems to be that hibernate somewhere mixes the primary keys sent to each object, and instead of inserting a legajo_id in empvarios, it inserts a persona_cuil.
Code for clases:
persona:
#Entity
#Table(name = "persona")
#Inheritance(strategy = InheritanceType.JOINED)
public class persona implements Serializable {
private static final long serialVersionUID = 2847733720742959767L;
#Id
#Column(name="persona_cuil")
private String persona_cuil;
#Column(name="nombre")
private String nombre;
#Column(name="apellido")
private String apellido;
#Column(name="fecha_nac")
private String fecha_nac;
#Column(name="direccion")
private String direccion;
#Column(name="localidad")
private String localidad;
#Column(name="provincia")
private String provincia;
#Column(name="pais")
private String pais;
#Column(name="fecha_muerte")
private String fecha_muerte;
#Column(name="fecha_alta")
private String fecha_alta;
#Column(name="fecha_baja")
private String fecha_baja;
#Column(name="mail")
private String mail;
#Column(name="plan_id")
private int plan_id;
public persona (){
this.setPlan_id(0);
}
//Getters and Setters
}
empleado:
#Entity
#Table(name = "empleado")
#Inheritance(strategy = InheritanceType.JOINED)
#PrimaryKeyJoinColumn(name="persona_cuil")
public class empleado extends persona implements Serializable {
private static final long serialVersionUID = -7792000781951823557L;
#Column(name="legajo_id")
private int legajo_id;
public empleado(){
super();
int leg = SentenceManager.ultimoRegistro("empleado");
if (leg == 0){ //this works fine, it just searches the last registry, if it exists, i uses the next available number
this.setLegajo_id(1);
}
else {
this.setLegajo_id(leg+1);
}
}
//Getters and Setters
}
empvarios:
#Entity
#Table(name="empvarios")
#PrimaryKeyJoinColumn(name="legajo_id")
public class empvarios extends empleado implements Serializable, ToPersona{
private static final long serialVersionUID = -6327388765162454657L;
#Column(name="ocupacion_id")
int ocupacion_id;
public empvarios() {
super();
this.setLegajo_id(super.getLegajo_id());
}
//Getters and setters
}
Now, if I try to insert a new empleado into the database, it works just fine... BUT if I try to insert an empvarios, in the place where should be legajo_id, hibernate places the persona_cuil (I tested this by removing the FK restriction on the data base)
Images below:
(cant post images due reputation restriction :/)
https://www.dropbox.com/sh/mu5c797adlf7jiv/AACnd8mx7GriSyq5OMKoddRna?dl=0
There you have the 3 photos, the name of the files shows which table is each one.
Any ideas on whats going on?
The problem was that the data base was wrongly mapped.
If anyone has this problem then you will have to rethink the structure of the DB.
As seen in the example i gave above, the database should look like this:
persona:
persona_id (PK-autoincemental)
empleado:
persona_id (FK to persona)
legajo_id
empvarios:
persona_id (FK to persona)
ocupacion_id
The reason this works like this is because you cannot have different ids to depend different clases within the data base. On the program side it "can" work like that, but it the data base it has to be mapped differently.
Thanks!

Categories

Resources