Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Cannot join entities By Foreign Key and partial PK
PostPosted: Tue May 30, 2017 3:16 am 
Newbie

Joined: Tue May 30, 2017 2:34 am
Posts: 4
I have two tables:

Order 1: n OrderDetail (one-to-many unidirectional relationship)

OrderEntity and OrderDetailEntity both extend a superclass BaseEntity:

Code:
@MappedSuperclass
@Inheritance
public abstract class BaseEntity {

    @EmbeddedId
    private BaseEntityPK compPK;
//getters and setters



The embedded class:

Code:
@Embeddable
@Inheritance
public class BaseEntityPK implements Serializable {

    @Column(name="CLIENT_KEY", nullable = false)
    private long clientKey;

    @Column(name = "GUID", nullable = false)
    private long guid;

    public BaseEntityPK() {
    }
    public long getClientKey() {
        return this.clientKey;
    }
    public void setClientKey(long clientKey) {
        this.clientKey = clientKey;
    }
    public long getGuid() {
        return this.guid;
    }
    public void setGuid(long guid) {
        this.guid = guid;
    }

    public BaseEntityPK(long clientKey, long guid) {
        this.clientKey = clientKey;
        this.guid = guid;
    }
}




The OrderEntity entity:

Code:
@Entity
@Table(name="ORDERS")

public class OrderEntity extends BaseEntity implements Serializable {

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumns
            ({@JoinColumn(name = "ORDERIDCLIENTGUID", referencedColumnName = "CLIENTGUID", nullable = false),
      @JoinColumn(name = "CLIENT_KEY", referencedColumnName = "CLIENT_KEY", nullable = false)
        })
    private Set<OrderDetailEntity> orderDetails = new HashSet<>();

//getters and setters



Code:
The OrderDetailEntity entity:

@Entity
@Table(name="ORDERDETAIL")

public class OrderDetailEntity extends BaseEntity implements Serializable {
//getters and setters


For both Orders and OrderDetail tables:

CLIENT_KEY and GUID columns represent the primary key
CLIENT_KEY and CLIENTGUID represent an unique key.


If I use the mappings above, I get the following exception:

Code:
Caused by: org.hibernate.AnnotationException: referencedColumnNames(CLIENTGUID, CLIENT_KEY) of ...entities.OrderDetailEntity.orderDetails referencing ...entities.OrderEntity not mapped to a single property



Is the a way in hibernate to join two tables after a foreign key column and a partial primary key column?


Top
 Profile  
 
 Post subject: Re: Cannot join entities after foreign key and partial PK
PostPosted: Tue May 30, 2017 3:43 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1527
There are multiple issues associated with your mapping:

1. You either use @MappedSuperclass or @Inheritance, but not both.
2. Why did you add the @Inheritance annotation on the @Embeddable? Composite identifiers or embeddables are not inheritable.
3. Unidirectional @OneToMany with @JoinColumn are not very efficient. As explained in this article, you are better off mapping the @ManyToOne side and use a mappedBy @OneToMany if you really need it anyway.
4. fetch = FetchType.EAGER is almost always a bad choice.

Quote:
Is the(re) a way in hibernate to join two tables by a foreign key column and a partial primary key column?


Sure, you can join by any column combination you want. However, you are better mapping that on the @ManyToOne side.

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
 Post subject: Re: Cannot join entities By Foreign Key and partial PK
PostPosted: Tue May 30, 2017 5:35 am 
Newbie

Joined: Tue May 30, 2017 2:34 am
Posts: 4
Thank you for the feedback.

I've corrected the issues specified in steps 1 and 2 but I'm still getting the same exception.


Top
 Profile  
 
 Post subject: Re: Cannot join entities By Foreign Key and partial PK
PostPosted: Tue May 30, 2017 11:44 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1527
Check out this test on my GitHub repo.

If that does not help, you can use two @JoinFormula. Check out this article to see how to use @JoinFormula.

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
 Post subject: Re: Cannot join entities By Foreign Key and partial PK
PostPosted: Tue Jun 06, 2017 10:09 am 
Newbie

Joined: Tue May 30, 2017 2:34 am
Posts: 4
In the test from the GitHub repo, the join between phone and employee entities if performed after the primary key from employee entity (company_id,employee_number) not after part of primary key and another foreign key. I also tried with @JoinFormula but I'm getting the same exception. I've used the following annotation:

Code:
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumnsOrFormulas({
            @JoinColumnOrFormula(formula=@JoinFormula(value="(SELECT a.id FROM ORDERDETAIL a WHERE a.client_key = client_key)", referencedColumnName="CLIENT_KEY")),
            @JoinColumnOrFormula(formula = @JoinFormula(value="SELECT a.orderidclientguid FROM ORDERDETAIL a WHERE a.orderidclientguid = clientguid", referencedColumnName="CLIENTGUID"))
    })
    private Set<OrderDetailEntity> orderDetails = new HashSet<>();


Top
 Profile  
 
 Post subject: Re: Cannot join entities By Foreign Key and partial PK
PostPosted: Tue Jun 06, 2017 10:15 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1527
Maybe the OrderDetailEntity does not have a composite key. It's not like you posted the code to know for sure.

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
 Post subject: Re: Cannot join entities By Foreign Key and partial PK
PostPosted: Wed Jun 07, 2017 3:04 am 
Newbie

Joined: Tue May 30, 2017 2:34 am
Posts: 4
I've specified in the first comment that both OrderEntity and OrderDetailEntity entities have the same composite primary key formed by CLIENT_KEY and GUID columns. This is is the superclass for both specified entities :

Code:
@MappedSuperclass
public abstract class BaseEntity {

// the embedded class containing the composite primary key
    @EmbeddedId
    private BaseEntityPK compPK;
//getters and setters


The embedded class containing the composite primary key is :

Code:
@Embeddable
public class BaseEntityPK implements Serializable {

    @Column(name="CLIENT_KEY", nullable = false)
    private long clientKey;

    @Column(name = "GUID", nullable = false)
    private long guid;

    public BaseEntityPK() {
    }
    public long getClientKey() {
        return this.clientKey;
    }
    public void setClientKey(long clientKey) {
        this.clientKey = clientKey;
    }
    public long getGuid() {
        return this.guid;
    }
    public void setGuid(long guid) {
        this.guid = guid;
    }

    public BaseEntityPK(long clientKey, long guid) {
        this.clientKey = clientKey;
        this.guid = guid;
    }
}


So, the primary key for both ORDER and ORDERDETAIL tables is the pair (CLIENT_KEY, GUID). I want to perform a join by CLIENT_KEY(partial primary key) and CLIENTGUID (foreign key) columns.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.