Hibernate delete row and foreign key row ManyToOne - java

I have the following two classes, one ReqCandAssociation can have many Comments and it is mapped like so. I need to figure out a way that when I delete a ReqCandAssociation it deletes all of its associated comments. Thanks
#Entity
#Table(name = "candidate_jobReq")
public class ReqCandAssociation implements Serializable {
#Id
private Integer candidateId;
#Id
private Integer jobId;
#Column(name = "reqStatus")
private String reqStatus;
#ManyToOne
#PrimaryKeyJoinColumn(name="candidateId", referencedColumnName="id")
private Candidate candidate;
#ManyToOne
#PrimaryKeyJoinColumn(name="jobId", referencedColumnName="id")
private JobReq jobReq;
public ReqCandAssociation(){
}
Second class
#Entity
#Table(name="comment")
public class Comment {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name="commentText")
private String commentText;
#Column(name="commentDate")
private Date commentDate;
#ManyToOne
#PrimaryKeyJoinColumn(name="reqCandAssociationId", referencedColumnName="id")
private ReqCandAssociation reqCandAssociation;
#ManyToOne
#PrimaryKeyJoinColumn(name="userId", referencedColumnName="id")
private User user;

Change this to the following, i'm making it bidirectional mapping.
#Entity
#Table(name = "candidate_jobReq")
public class ReqCandAssociation implements Serializable {
#Id
private Integer candidateId;
#Id
private Integer jobId;
#Column(name = "reqStatus")
private String reqStatus;
#OneToMany(cascade = { CascadeType.ALL }) //this is added here.
#JoinColumn(name ="reqCandAssociationId")
private Set<Comment> comments;
-----
Readup more on the cascade options. All cascade types are all|none|save-update|delete|all-delete-orphan|delete-orphan
The cascade all will delete all the comments associated to this class.

Related

JPA - Map child entity class to parent when parent has two child objects

I have a Shipment Entity class where there are two ShipmentAddress, one for the delivery address and the other, the destination address:
#Entity
#Table(name = "shipment")
public class Shipment {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne
private AppUser user;
#OneToOne(cascade = CascadeType.ALL)
private ShipmentAddress fromAddress;
#OneToOne(cascade = CascadeType.ALL)
private ShipmentAddress toAddress;
}
I have a ShipmentAddress Entity class where it looks like this:
#Entity
public class ShipmentAddress {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(nullable = false)
private String street1;
private String street2;
#OneToOne(mappedBy = "fromAddress")
private Shipment shipment;
#OneToOne(mappedBy = "toAddress")
private Shipment shipment;
}
I think we can agree that it is redunant to have two properties to define a Shipment inside ShipmentAddress, because they both point to the same Shipment. In ShipmentAddress class, I want to be able to have one Shipment in the ShipmentAddress Entity. JPA does not support multiple #OneToOne annotations for the same entity class. How can I accomplish this?

Hibernate #ManyToMany with extra columns

So I've been trying the solutions out there to map a ManyToMany relationship with extra columns but none of them is working for me and I don't know what am I doing wrong.
The Many to Many relationship is between Patient and Disease (a Patient can have multiple diseases and a Disease can be suffered by many Patients). The time attribute means "the type of the disease" (acute, chronic...)
My classes are:
#Entity
#Table(name="patient")
public class Patient{
#Id
#NotNull
#Column(name="nss")
private String NSS;
//Some attributes
#OneToMany(mappedBy = "patient")
private Set<PatientDisease> diseases = new HashSet<PatientDisease>();
//Empty constructor and constructor using fields omitted
//Getters and setters ommited
}
,
#Entity
#Table(name="disease")
public class Disease{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private Integer id;
#OneToMany(mappedBy = "disease")
private Set<PatientDisease> patients = new HashSet<PatientDisease>();
//Constructors and getters and setters ommited for brevity
}
Associated class
#Entity
#Table(name = "Patient_Disease")
#IdClass(PatientDiseaseID.class)
public class PatientDisease{
#Id
#ManyToOne(fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
#JoinColumn(name = "nssPatient", referencedColumnName = "id")
private Patient patient;
#Id
#ManyToOne(fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
#JoinColumn(name = "diseaseID", referencedColumnName = "id")
private Disease disease;
#Column(name="time")
private String time;
//GETTERS AND SETTERS OMMITED FOR BREVETY. Constructor NOT Needed following the example
}
The id class:
#Embeddable
public class PatientDiseaseId implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "nssPatient")
private String patient;
#Column(name = "diseaseID")
private Integer disease;
//getters and setters
//hashCode and equals
}
My main app:
...
List<Diseases> diseases = sesion.createQuery("from Disease").getResultList();
System.out.println("Diseases: ");
for(Disease d: diseases) {
System.out.println(d.getName());
for(PatientDisease pd: e.getPatientDisease()) {
System.out.println(pd.getPatient().toString());
}
}
...
When running the main App I get the exception on line 5 (2nd for loop):
Exception in thread "main" org.hibernate.PropertyAccessException: Could not set field value [1] value by reflection : [class entities.PatientDisease.diseases] setter of entities.PatientDisease.diseases
I have tried some solutions here in Stack Overflow an some others that I found on the Internet, but I can't get them to work and I don't know why
Because you are using #IdClass you don't need to annotate PatientDiseaseId with #Embedded and #Column. And you have to refer to the entities.
This is what it should look like:
public class PatientDiseaseId implements Serializable {
private static final long serialVersionUID = 1L;
private Patient patient;
private Disease disease;
//getters and setters
//hashCode and equals
}

Spring data jdbc - Specific join, specific mapping

I've got following two tables:
Customer
id
name
Order
id
product_name
customer_id
with a 1 to 1 relation
and java entities:
#Data
public class Customer{
#Id
private Long id;
private String name;
}
#Data
public class Order{
#Id
private Long id;
#Column("id")
private Customer customer; //i want to somehow map this
private String productName;
}
and a controller
#Controller
public class MyController{
//...
#GetMapping("/")
public String getmap(Model m){
System.out.println(repository.findAll()) //prints "nullrows" due to wrong sql statement
return "mytemplate";
}
}
my current issue is, that spring is executing following sql statement:
SELECT Order.id, Order.product_name, Customer.id, Customer.name
FROM Order LEFT OUTER JOIN Customer ON Customer.id = Order.id
what i actually want is to join on Customer.id = Order.customer_id while leaving the classes as they are i.e. the customer reference needs to stay in order.
i've tried every annotation that i could find so far and have made no progress.
EDIT:
I am not allowed to use jpa/hibernate
One workaround is to do the following:
#Data
public class Customer{
#Id
private Long id;
private String name;
}
#Data
public class Order{
#Id
private Long customerId;
private Long id;
#Column("id")
private Customer customer; //i want to somehow map this
private String productName;
}
causing this to automatically join on Customer.id = Order.customer_id
This does not look like a good fix however.
You can use #OneToOne and #JoinColumn annotations for your One-to-One relationship:
#Data
public class Customer{
#Id
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "order_id", referencedColumnName = "id")
private Order order;
}
#Data
public class Order{
#Id
#Column(name = "id")
private Long id;
#Column(name = "product_name")
private String productName;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "customer_id", referencedColumnName = "id")
private Customer customer;
}

Java JPA Realtions

I am doing an application where I need 2 entities: User and Car.
public class User{
private long id;
private String name;
}
public class Car{
private long id;
private User firstUser;
private User secondUser;
}
So my table cars_info info will contain
RENT(date), FIRST_USER(id), SECOND_USER(id)
How do I connect this using hibernate? I need unidirectional relation. I tried OneToOne, ManyToOne but neither of that works.
Check that you're properly naming the column on your CAR table vs the reference column on the USER table. Example below:
#Entity
#Table(name = "USER")
public class User {
#Id
#Column(name = "USER_ID")
private long id;
#Column(name = "NAME")
private String name;
}
#Entity
#Table(name = "CAR")
public class Car {
#Id
#Column(name = "CAR_ID")
private long id;
#ManyToOne
#JoinColumn(name = "FIRST_USER_ID", referencedColumnName = "USER_ID")
private User firstUser;
#ManyToOne
#JoinColumn(name = "SECOND_USER_ID", referencedColumnName = "USER_ID")
private User secondUser;
}

#OneToOne Hibernate with annotations. Can't properly save

I can't make my foreign keys auto generate using hibernate and jpa with annotations. Everything seems ok, The entries are saved in database. All the date come from one form which, when submited creates an User object with ModelAttribute and then saves it in Database.
Here are my beans. Anything else i should add ?
#Entity
#Table(name="adress")
public class Adress implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="adress_id")
private Integer adressId;
#NotBlank(message="The city must be completed")
#Column(name="city")
#Size(min=5,max=30)
private String city;
#NotBlank(message="The street must be completed")
#Column(name="street")
#Size(min=5,max=30)
private String street;
#NotNull(message="The street number must be completed")
#NumberFormat
#Column(name="street_no")
private Integer streetNo;
#OneToOne
#JoinColumn(name="user_id")
private User user;}
and the other one:
#Entity
#Table(name="users")
public class User implements Serializable {
#Id
#Column(name="user_id")
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer userId;
#NotBlank(message="Username can't be blank")
#Size(min=5,max=30)
#Column(name="username")
private String username;
#NotBlank(message="Password field can't be blank")
#Size(min=5,max=30)
#Column(name="password")
private String password;
#NumberFormat
#NotNull(message="Age field must not be blank")
#Column(name="age")
private Integer age;
#Column(name="message")
#Size(min=0,max=100)
private String message;
#Column(name="date")
#DateTimeFormat(pattern="dd/mm/yyyy")
private Date dateCreated;
#OneToOne(mappedBy="user",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
private Adress adress;
+getters and setters for them
public void save(T entity){
sessionFactory.getCurrentSession().save(entity);
}
If I understand you correctly and you're trying to get Hibernate to set the foreign key on your related record this might help. Try getting rid of mappedBy and instead specify the JoinColumn. This works for me on a one to many:
The order:
#Entity
#Table(name = "`order`")
public class Order implements Serializable {
#Id
#GeneratedValue
private Long id;
// Order columns...
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "order_id")
private Set<Item> items;
}
The item:
#Entity
#Table(name = "item")
public class Item implements Serializable {
#Id
#GeneratedValue
private Long id;
// Item columns...
#ManyToOne(optional = false)
#JoinColumn(name = "order_id", referencedColumnName = "id", nullable = false)
private Order order;
}
in adress class
#OneToOne(mappedBy="adress")
private User user;
and in user class
#OneToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER,optional=false)
#PrimaryKeyJoinColumn
private Adress adress;

Categories