Mathew
Mathew

Reputation: 71

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

Upvotes: 1

Views: 92

Answers (1)

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();
}

Upvotes: 1

Related Questions