0

I was testing out a simple code for practicing hibernate entities which has two entities: Employee and Address. An employee can have many addresses. So it's a Employee is OneToMany relationship with Address. And Address is ManyToOne relationship with Employee.


Employee entity

import lombok.*;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Set;

@Entity
@Table(schema = "hibernate_entity_demo", name="employee")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name="first_name")
    private String fname;

    @Column(name="last_name")
    private String lastname;

    @Column(name="email")
    private String email;

    @OneToMany(mappedBy = "employee")
    private Set<Address> addressSet;

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", fname='" + fname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", email='" + email + '\'' +
                ", address='" + addressSet+
                '}';    
    }
}

Address entity

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(schema = "hibernate_entity_demo", name="address")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Address implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "city")
    private String city;

    @ManyToOne
    @JoinColumn(name="employee_id")
    private Employee employee;

    @Override
    public String toString() {
        return "Address{" +
                "id=" + id +
                ", city='" + city + '\'' +
                ", employee='" + employee.getFname() + " "+ employee.getLastname() +
                "'}";
    }
}

My schema

CREATE SCHEMA IF NOT EXISTS hibernate_entity_demo;

CREATE TABLE IF NOT EXISTS hibernate_entity_demo.employee (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    first_name VARCHAR(32) ,
    last_name VARCHAR(32) ,
    email VARCHAR(32)
);

CREATE TABLE IF NOT EXISTS hibernate_entity_demo.address (
    id          INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    city        VARCHAR(32),
    employee_id INT ,
    FOREIGN KEY (employee_id) REFERENCES hibernate_entity_demo.employee(id)
)

My hibernate.cfg.xml

<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_entity_demo</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>

I thought I have setup everything correctly so I ran the following code where I create the entities and persist them:


tx = session.beginTransaction();

Employee emp = Employee.builder()
        .fname("John").lastname("Doe").
        email("example@gmail.com").build();
Address addr = Address.builder().city("Los Angeles").employee(emp)
        .build();
emp.setAddressSet(new HashSet<Address>(Arrays.asList(addr)));
session.persist(addr);
session.persist(emp);

The Problem

Everything ran fine but here's the problem. The employee_id field in the Address table is null. This is what I got when I look at my database directly.

Employee table
id email first_name last_name
1 example@gmail.com John Doe
Address table
id city employee_id
1 Los Angeles

What I Expect

I'm expecting my tables to look like this instead with the employee_id of address with id 1 to be 1.

Employee table
id email first_name last_name
1 example@gmail.com John Doe
Address table
id city employee_id
1 Los Angeles 1

I have tried changing the hbm2ddl.auto to update but it didn't work. I also tried running the following code to see if the address's employee is correct.

Employee e1 = session.get(Employee.class,1);
Address a1 = session.get(Address.class, 1);
System.out.println(e1);
System.out.println(a1);

The output is:

Employee{id=1, fname='John', lastname='Doe', email='example@gmail.com', address='[Address{id=1, city='Los Angeles', employee='John Doe'}]}
Address{id=1, city='Los Angeles', employee='John Doe'}

As you can see, the Address a1 has the correct Employee e1 when I printed out but the foreign key is still not in the table.

Any advice?

CitoC
  • 3
  • 2
  • Just try to use List instead of Set for more info : https://stackoverflow.com/questions/1035008/what-is-the-difference-between-set-and-list https://stackoverflow.com/questions/17985029/hashset-vs-arraylist – InFM8 Dec 05 '22 at 07:23
  • With the data in you tables, your output shouldn't be possible. Besides that, you either want to cascade inserts or, you want to swap the insert statements. Currently you persist the address before the employee. At that point, the employee has no ID, that is the reason you don't get any ID in you database. Persist the employee first and the address after – XtremeBaumer Dec 05 '22 at 07:59
  • Try to save first `employee` then the `address` . If you save first the address, employee doesn't have ID. Maybe you need to assigned the employee to the response from the db and then save it ( Not sure about this, you just need to check) : – Емилиян Йорданов Dec 05 '22 at 10:19

1 Answers1

0

Okay fixed. Needed to persist the Employee before the Address. The correct order should be below.

session.persist(emp);
session.persist(addr);
CitoC
  • 3
  • 2