Bart Weber
Bart Weber

Reputation: 1216

JPA - How to add child entities to aggregate roots

It's the first time I apply DDD. I use EclipseLink. I've the following issue. My root entity has a child entity (child). This child entity has also a child entity (childSpecs).

I want to make the root entity (root) responsible for creating and adding child entities:

root.addChild(arg1, agr2);

But child can't exist without childSpecs. I made child responsible for creating childSpecs.

So when calling addChild(arg1, arg2) the objects child and childSpecs are created and are related to eachother and root. But childSpecs has a mandatory field which keeps the id of child. But when child is created it hasn't yet an id. That will be created when it gets persisted. (Currently I use the JPA functionality TableGenerator to generate my surrogate key values.) Does someone know a solutions to solve this. My thought was to build my own id-generator. But that might be a little bit complicated when taking in acount concurrency.

Additional info:

@Entity
@Table (name = "root")
public class Root implements Serializable {
    @Id
    @Basic (optional = false)
    @Column (name = "root_id")
    private Integer        rootId;

    @OneToMany (mappedBy = "root")
    private List<RootChild>   rootChildList;

-

@Entity
@Table (name = "root_child")
public class RootChild implements Serializable {
    @Id
    @Basic (optional = false)
    @Column (name = "root_child_id")
    private Integer           rootChildId;

    @JoinColumn (name = "root_id", referencedColumnName = "root_id")
    @ManyToOne
    private Root               root;

    @OneToMany (cascade = CascadeType.ALL, mappedBy = "rootChild")
    private List<RootChildSpecs> rootChildSpecsList;

-

@Entity
@Table (name = "root_child_specs")
public class RootChildSpecs implements Serializable, Mutable<RootChildSpecs> {
    @EmbeddedId
    protected RootChildSpecsPK rootChildSpecsPK;

    @JoinColumn (
        name                 = "root_child_id",
        referencedColumnName = "root_child_id",
        insertable           = false,
        updatable            = false
        )

     @ManyToOne (optional = false)
     private RootChild          rootChild;

-

@Embeddable
public class RootChildSpecsPK implements Serializable {
    @Basic (optional = false)
    @Column (name = "root_child_id")
    private int rootChildId;

    @Basic (optional = false)
    @Column (name = "d_rec")
    private int dRec;

    @Basic (optional = false)
    @Column (name = "t_rec")
    private int tRec;

Upvotes: 3

Views: 2142

Answers (2)

James
James

Reputation: 18379

I would recommend not using an EmbeddedId and instead put the @Id on your @ManyToOne to RootChild and use an @IdClass.

See, http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#JPA_2.0

Upvotes: 1

Chris
Chris

Reputation: 21145

JPA 2.0 allows deriving IDs from references, allowing you to mark the RootChildSpecs->RootChild as being part of rootChildSpecs' ID and pulling the value from it when it gets generated. A simple example is here http://wiki.eclipse.org/EclipseLink/Examples/JPA/2.0/DerivedIdentifiers

You can mark the relationship using @mapsId to point to the attribute it mapps in the embeddedid since Embeddedid and pk classes cannot contain relationships themselves.

Upvotes: 1

Related Questions