Depressio
Depressio

Reputation: 1379

Generating ID of parent in parent-child persistence

I've got a one-to-many parent-child relationship, and I want to persist the entire thing only once. The problem I'm having is that the child has the ID of the parent in it, but at the time of persistence, it's not able to get that ID since it's generated. Here's the setup I've got so far:

public class Parent
{
    @Id
    @GeneratedValue(generator = "parent-id-gen")
    @GenericGenerator(name = "parent-id-gen", strategy = "increment")
    @Column(name = "id", nullable = false)
    private long ID;

    // some other fields

    @OneToMany(orphanRemoval = true, cascade = CascadeType.ALL)
    @JoinColumn(name = "parent_id")
    private List<Child> children;
}

public class Child
{
    @Id
    @GeneratedValue(generator = "child-id-gen")
    @GenericGenerator(name = "child-id-gen", strategy = "increment")
    @Column(name = "id", nullable = false)
    private long ID;

    @Column(name = "parent_id", nullable = false)
    private long parentID;

    // some other fields
}

The database (PostgreSQL) looks like this, if it matters:

CREATE TABLE parent
(
  id integer NOT NULL,
  ... other fields,
  PRIMARY KEY (id)
);

CREATE TABLE child
(
  id integer NOT NULL,
  parent_id integer NOT NULL,
  ... other fields,
  PRIMARY KEY (id),
  UNIQUE (parent_id, ... other fields)
);

I want to only do a single org.hibernate.Session.saveOrUpdate(parentObject), but it's failing my unique key on the child table because the parentID is being set to 0 all the time, rather than the generated ID from the parent.

Is there any way to do this?

I'm thinking Hibernate inserts first, then updates the child with the parent ID so there's no way to do this as the database is currently defined. I'll probably have to remove the unique key as a result, which is unfortunate... if there's a way around that, let me know!

Edit: Added DB info since it's probably pertinent.

Upvotes: 1

Views: 1695

Answers (1)

Francisco Spaeth
Francisco Spaeth

Reputation: 23913

The idea behind Hibernate is that your model classes are abstracted from identification stuff between relations. Meaning private long parentID could be changed to private Parent parent. This will let hibernate know how to control it, and if you need parent's Id, you can do something like child.getParent().getId()

Upvotes: 1

Related Questions