gozluklu_marti
gozluklu_marti

Reputation: 55

JPA: Reference column in the child entity is null when using unidirectional @OneToMany

I have two entity classes.

Order.java

@Entity
@Table(name = "order_table")
public class Order implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

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

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "order_id", referencedColumnName = "id", nullable = false, insertable=false, updatable=false)
    private Set<Item> items;

    // getters & setters & toString

Item.java

@Entity
@Table(name = "item")
public class Item implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

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

    @Column(name = "order_id", nullable = false)
    private Long orderId;

    // getters & setters && toString

I created a test class like this:

@Test
public void createOrderWithItems() {

    Item item = new Item();
    item.setName("Iron Man");

    Order order = new Order();
    order.setName("Toy");
    order.getItems().add(item);

    Order created = service.createOrder(order);

    Order orderById = service.getOrderById(order.getId());
    System.out.println("Created Order: " + orderById);

    Item itemById = service.getItemById(item.getId());
    System.out.println("Created item: " + itemById);


    Assert.notNull(created.getId(), "Order ID is Null");
}

Test is green but if you check output, you'll see that orderId field in the Item class is null.

Created Order: Order{id=1, name='Toy', items=[Item{id=2, name='Iron Man', orderId=null}]}
Created item: Item{id=2, name='Iron Man', orderId=null}

Does JPA not update this column in the db automatically? Is this column is redundant? If so, how can I retrieve this information from test code?

Upvotes: 1

Views: 489

Answers (1)

Cyril Silver
Cyril Silver

Reputation: 43

You need to set orderId explicitly.

item.setOrderId(order.getId());
order.getItems().add(item);

You can create a method addItem(Item item) in your Order class and hide this logic within it.

Cascading will create an entry in db but it won't initialize field. JPA annotations just indicate to JPA provider how to perform mapping between entity and table.

Moreover, check your annotations. @JoinColumn should be used in the entity which owns the relationship (the corresponding table has column as a foreign key). Check the top answer for this question for detailed explanations: What's the difference between @JoinColumn and mappedBy when using a JPA @OneToMany association

Upvotes: 1

Related Questions