简体   繁体   中英

How to populate a Child Composite Key from the Parents Sequence value (Hibernate, JPA)?

I have a situation were I have a class Called Order with a generated OrderID :

    @Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_gen")
@SequenceGenerator(name = "seq_gen", sequenceName = "OID_SEQ1")
@Column(name = "ORDER_ID",nullable = false)
public long getOrderId()
{
    return this.OrderId;
}

it also has a one-to-many mapping with a class/ table called items:

    @OneToMany(fetch = FetchType.LAZY,mappedBy = "orders",targetEntity = Items.class)
public Set<Items> getItems()
{
    return this.items;
}

within the items class is an embedded/composite id:

    @EmbeddedId
@AttributeOverrides({@AttributeOverride(name = "OrderId",column = @Column(name = "ORDER_ID",nullable = false)),
        @AttributeOverride(name = "role",column = @Column(name = "ROLE",nullable = false,length = 10))})
public ItemId getId()
{
    return this.id;
}

My problem is part of this id is the primary key of the parent Order.class. In other words the sequence value. This means I cannot set this value anywhere and when I call:

entitymanager.persist(order);

The parent Order object writes to the db BUT none of the items within the Set are persisted. There is only one insert statement and all the references to orderId in the Items objects are null????

How can I populate these ID's with the generated Seq ID?

Many thanks for any help with this!

Eventually figured this out with the help of another post: onetomany-and-composite-primary-keys The answer was in fact quite simple. We need to use the Casade annotation to casade the Id down to the child object. so the one to many mapping above becomes:

@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,mappedBy = "orders",targetEntity = Items.class) public Set<Items> getItems() {     return this.items; } 

When implementing this review the different cascade types.

Good luck

I'm not 100% sure based on your question, but I think you're looking for EntityManager.flush():

// Create an Order with no items, get its order ID
Order order = new Order(...);
em.persist(order);
// Order should have the generated ID filled in after this call to flush()
em.flush();  

// Create all the items for an order, filling in the Order ID into each item's
// composite key
for(...) {
    // create new item
    Item item = new Item(...);
    // populate other parts of the Item's composite key here
    // then fill in the OrderID part of the composite key
    item.getId().setOrderId(order.getOrderId());
    // add new item to the order's collection
    order.addItem(item);
}

You shouldn't need another call to persist() after filling in the items.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM