简体   繁体   中英

JPA make a part of the composite foreign key part of primary key

I was looking at all the possible Google searches and Stackoverflow searches but couldn't find what I was looking for. My problem is that there is a class A and a class B, class A has a composite primary key and class B has a primitive primary key. These classes (tables) are joined with a class called C, I need this because there is other data with the join (examples at the bottom). In class C I obviously have class B's and A's primary keys as foreign keys, but I need the first property of the class B's composite key and A's foreign key to be the primary key in class C.

It is kinda hard to understand it with just text so here is the example:

public class CompositeId implements Serializable {
    private Long id;

    private Long version;

    // Other stuff...
}

@Entity
@IdClass(CompositeId.class)
public class A {
    @Id
    private Long id;

    @Id
    private Long version;

    private String name;

    private String creatorName;

    // Other stuff...
}

@Entity
public class B {
    private Long id;

    private String name;

    // Othet stuff...
}

public class CompositeJoinId implements Serializable {
    private Long aId; // Should equal to aReference's id property.

    private Long bId; // Should equal to bReference's id property.

    // Other stuff...
}

@IdClass(CompositeJoinId.class)
@Entity
public class C {
    @Id
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="a_id", referencedColumnName="id"),
        @JoinColumn(name="a_version", referencedColumnName="version")
    })
    private A aReference;

    @Id
    @ManyToOne
    @JoinColumn(name = "b_id")
    private B bReference;

    private Long day;

    // Other stuff...
}

Is there a way to make this happen? All my finding use only a class where both of the foreign composite keys are used, but I only need/want one.

I'm not entirely sure I understand your question; but I would map your classes like this (the primary difference being CompositeJoinId ):

public class CompositeId implements Serializable {
    private Long id;

    private Long version;

    // Other stuff...
}

@Entity
@IdClass(CompositeId.class)
public class A {
    @Id
    private Long id;

    @Id
    private Long version;

    private String name;

    private String creatorName;

    // Other stuff...
}

@Entity
public class B {
    @Id
    private Long id;

    private String name;

    // Othet stuff...
}

public class CompositeJoinId implements Serializable {
    private Long aId;

    private Long bReference; // matches name of @Id attribute and type of B PK

    // Other stuff...
}

@IdClass(CompositeJoinId.class)
@Entity
public class C {
    @Id
    @Column(name = "a_id", insertable = false, updatable = false)
    Long aId;

    @Id
    @ManyToOne
    @JoinColumn(name = "b_id")
    private B bReference;

    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="a_id", referencedColumnName="id"),
        @JoinColumn(name="a_version", referencedColumnName="version")
    })
    private A aReference;

    private Long day;

    // Other stuff...
}

These are examples of derived identities; and derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.

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