'Hibernate one-to-one cascade-all don't work
'Dear masters, currently learning Spring+Hibernate. I added HibernateUtil class to use it after for creating/deleting etc commands. I used cascadeALL for one-to-one mapping and when i run delete or create classes, they update only Instructor table in db, not related Instuctor Detail table. It works, if i write commands like in CreateDemo class - session.save(tempInstructor); session.save(tempInstructorDetail); but as i understand i should be able to write only session.save(tempInstructor); - and this would update also linked table. The same for DeleteDemo. Why cascade = CascadeType.ALL does not work?'
enter code here
@Entity
@Table(name = "instructor")
public class Instructor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column( name = "id")
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "instructor_detail_id")
private InstructorDetail instructorDetail;
enter code here
@Entity
@Table(name = "instructor_detail")
public class InstructorDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "youtube_channel")
private String youtubeChannel;
@Column(name = "hobby")
private String hobby;
enter code here
@SpringBootApplication
public class CreateDemo {
public static void main(String[] args) {
SpringApplication.run(CreateDemo.class, args);
Instructor tempInstructor = new Instructor('Vilma', 'Kalna', '[email protected]');
InstructorDetail tempInstructorDetail = new InstructorDetail('www.vilma-
teaching.com/youtube', 'teaching');
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
session.beginTransaction();
System.out.println('Saving instructor: ' + tempInstructor);
//this will also save the details object
//because of CascadeType.ALL
session.save(tempInstructor);
session.save(tempInstructorDetail);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
enter code here
public class DeleteDemo {
public static void main(String[] args) {
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
session.beginTransaction();
int theId = 2;
Instructor tempInstructor = session.get(Instructor.class, theId);
System.out.println('Found instructor: ' + tempInstructor);
if(tempInstructor != null){
System.out.println('Deleting: ' + tempInstructor);
//will also delete associated details obj (Cascade)
session.delete(tempInstructor);
}
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
enter code here
public class HibernateUtil {
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
Configuration configuration = new Configuration();
// Hibernate settings equivalent to hibernate.cfg.xml's properties
Properties settings = new Properties();
settings.put(Environment.DRIVER, '');
settings.put(Environment.URL, '');
settings.put(Environment.USER, '');
settings.put(Environment.PASS, '');
settings.put(Environment.DIALECT, 'org.hibernate.dialect.MySQL5Dialect');
settings.put(Environment.SHOW_SQL, 'true');
settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, 'thread');
configuration.setProperties(settings);
configuration.addAnnotatedClass(Instructor.class);
configuration.addAnnotatedClass(InstructorDetail.class);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Exception e) {
e.printStackTrace();
}
}
return sessionFactory;
enter code here
Solution 1:[1]
While creating the entities there should be Bi-directional mapping. Create the below attribute in instructor detail and create getters and setters for it.
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "instructor_id")
private Instructor instructor;
Create the below function inside the instructor detail entity
public void add(Instructor instructor) {
this.instructor = instructor;
instructor.setInstructorDetail(this)
}
While creating the instructor call the above function using instructor detail object that is related to instructor object like,
instructorDetail.add(instructor);
Solution 2:[2]
The InstructorDetail class also needs to do cascading because it should be bi-direction.
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "instructor_id")
private Instructor instructor;
And create setter and getter for the instructor. I hope this will work
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
