gpushkas
gpushkas

Reputation: 37

Hibernate Inner Join by non-primary key

Is there any way to create inner join 1X1 relation between 2 tables on fields that are not marked as @Id?

Table A:

@Entity
public Class AEntity
@Id 
private Long id
@Column
private String woCode
@Transient
private BEntity bEntity

Table B:

@Entity
public Class BEntity
@Id
private Long id
@Column
private String refId
@Column
private String title

What needs to be done to get finally following SQL:

select * from A inner join B on A.woCode=B.refId

And while querying AEntity, bEntity field will be populated with corresponding data from Table B.

Upvotes: 2

Views: 1929

Answers (1)

Bonifacio
Bonifacio

Reputation: 1502

Yeah, there's a way to do that.

First, you must remove the @Transient annotation of bEntity attribute inside AEntity class. @Transient is a annotation to define attributes you do not want to persist into the database.

If you try to deploy your application after removing the @Transient annotation you will get a Hibernate mapping error which is the expected behavior, because the attribute bEntity will not be mapped inside your database. So, to create the right mapping you should do something like this:

@ManyToOne
@JoinColumn(name = "refId", referencedColumnName = "refId")
private BEntity bEntity;

Explaining:

@ManyToOne is the annotation used to map relationship between entities, this annotation must be used to generate a link between your two entitie. Without creating this link you will not be able to populate this field directly from one query.

@JoinColumn is the annotation used to map what column you will use to create a link between your entities. The attribute "referencedColumnName" is where you must specify what column you will use as relationship.

Completing this tasks, AEntity must be able to see BEntity inside your queries, and also be able to retrieve BEntity fields directly from AEntity.

To accomplish your needs you can try the following query (remember, it is written in jpql):

SELECT a FROM AEntity a WHERE a.woCode = a.bEntity.refId

This way you should be able access all fields of BEntity through AEntity.

Please, let us know if this solve your problem.

Upvotes: 2

Related Questions