Search code examples
hibernatehibernate-mapping

Hibernate - column is null in each row (@JoinColumn)


I've got problem with relations between entities... I try to save object Subject, which contains list of objects Test. In table subjects I've got subject with id '1'. When I don't use cascade = CascadeType.ALL, I haven't got table test. When i use cascade I've got test table, but subject_id column is NULL in each row. I give up. Where am I stupid? Below my code.

package com.mizio.model;
import lombok.*;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "subjects")
public class Subject {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "subject_id",
        updatable = false,
        nullable = false)
private int subjectID;

@Column(name = "subject_name")
private String subjectName;

@OneToMany(mappedBy = "subject",
        targetEntity = Test.class,
        fetch= FetchType.LAZY,
        cascade = CascadeType.ALL)
private List<Test> tests = new ArrayList<>();

}

package com.mizio.model;
import lombok.*;
import javax.persistence.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "tests")
public class Test {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "test_id")
private int testID;

@ManyToOne(targetEntity = Subject.class,
        fetch = FetchType.EAGER)
@JoinColumn(name = "subject_id", referencedColumnName = "subject_id")
private Subject subject;

@Column(name = "test_name")
private String testName;

}

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test_generator?serverTimezone=UTC</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
        <property name="connection_poolsize">1</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">create</property>
        <property name="current_session_context_class">thread</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <mapping class="com.mizio.model.Subject" />
        <mapping class="com.mizio.model.Test" />
    </session-factory>
</hibernate-configuration>

How I TRY my code:

public class Main {

    public static void main(String[] args) {

        //create session factory
        SessionFactory factory = new Configuration()
                                .configure("hibernate.cfg.xml")
                                .addAnnotatedClass(Subject.class)
                                .addAnnotatedClass(Test.class)
                                .buildSessionFactory();

        //create session
        Session session = factory.getCurrentSession();
        try{
            //use the session object to save Java object
            //create 3 student objectS
            System.out.println("Creating subject objectS...");
            Test test1 = Test.builder()
                    .testName("Test 1")
                    .build();
            Test test2 = Test.builder()
                    .testName("Test 2")
                    .build();
            List<Test> tests = new ArrayList<>();
            tests.add(test1);
            tests.add(test2);
            Subject subject1 = Subject.builder()
                    .subjectName("Przedmiot 1")
                    .tests(tests)
                    .build();

            //start a transaction
            session.beginTransaction();
            //save the student object
            System.out.println("Saving the subjectS...");
            session.save(subject1);
            //commit transaction
            session.getTransaction().commit();
            System.out.println("Done!");
        }
        finally {
            factory.close();
        }
    }
}

MySQL Workbench results:

subjects table [![tests table][2]][2]

--------------------------------------------------------------------------------------------------------- [2]: https://i.sstatic.net/mlUn9.png


Solution

  • Probably because of auto generated Ids. Try this

    try {
      //use the session object to save Java object
      //create 3 student objectS
      System.out.println("Creating subject objectS...");
    
      //start a transaction
      session.beginTransaction();
      Subject subject1 = Subject.builder().subjectName("Przedmiot 1")
                        .build();
      System.out.println("Saving the subjectS...");
      session.save(subject1);
      //subject1 is now a managed identity and also should have an id
      System.out.println("Auto generated Id for subject1 : " 
                                   + subject1.getSubjectID());
      Test test1 = Test.builder().testName("Test 1").setSubject(subject1)
                   .build();
      Test test2 = Test.builder().testName("Test 2").setSubject(subject1)
                   .build();
      List<Test> tests = new ArrayList<>();
      tests.add(test1);
      tests.add(test2);
      subject1.setTests(tests);
      // since subject1 is managed entity at this point and cascade is ALL,
      // all tests should be saved automatically
      session.getTransaction().commit();
      System.out.println("Done!");
    }
    finally {
      session.close();
       factory.close();
    }