【问题标题】:Hibernate one-to-one cascade-all don't workHibernate 一对一级联 - 都不起作用
【发布时间】:2022-01-12 16:55:17
【问题描述】:

'各位高手,目前正在学习Spring+Hibernate。我添加了 HibernateUtil 类以在创建/删除等命令后使用它。我使用 cascadeALL 进行一对一映射,当我运行删除或创建类时,它们只更新数据库中的 Instructor 表,而不是相关的 Instuctor Detail 表。它可以工作,如果我在 CreateDemo 类中编写命令 - session.save(tempInstructor); session.save(tempInstructorDetail);但据我所知,我应该只能写 session.save(tempInstructor); - 这也会更新链接表。 DeleteDemo 也是如此。为什么 cascade = CascadeType.ALL 不起作用?'

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', 'vilma@gamil.com');
   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

【问题讨论】:

  • 你在哪里设置instructor.instructorDetail字段?你好像没有这样做,所以没有什么可以级联的。
  • 谢谢!我没有,我需要 tempInstructor.setInstructorDetail(tempInstructorDetail);在 session.beginTransaction() 之前;运行方法时。现在可以使用了。

标签: java spring hibernate one-to-one cascade


【解决方案1】:

在创建实体时应该有双向映射。在讲师详细信息中创建以下属性并为其创建 getter 和 setter。

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "instructor_id")
    private Instructor instructor;
    

在讲师详细信息实体中创建以下函数

public void add(Instructor instructor) {
       this.instructor = instructor;
       instructor.setInstructorDetail(this)
    }

在创建讲师时,使用与讲师对象相关的讲师详细信息对象调用上述函数,例如,

instructorDetail.add(instructor);

【讨论】:

  • 我已经有级联了,我也不需要从另一边。我的工作中缺少一个代码部分,现在添加它就可以了。但似乎我不允许回答我自己的问题,它被删除了,所以只是让信息表明这是错误的 - 只从一侧级联!
【解决方案2】:

InstructorDetail 类也需要做级联,因为它应该是双向的。

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "instructor_id")
private Instructor instructor;

并为讲师创建 setter 和 getter。我希望这会奏效

【讨论】:

  • 这是不正确的,你不需要来自另一边的级联。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-02
  • 1970-01-01
  • 2016-05-03
  • 2012-01-26
  • 2011-03-13
  • 1970-01-01
相关资源
最近更新 更多