Reputation: 995
I am designing two entities, one called Country
and one called CountryDetail
. From the perspective of tables, the COUNTRY
table will be the parent table, and the COUNTRY_DETAIL
table will be the child table. In the COUNTRY
table, there will be a unique attribute called COUNTRY_CODE (note this is not a primary key; the primary key will be a numeric sequence based value). This code will be a foreign key to connect to the child table, and in this child table, each COUNTRY_CODE
from the parent table will have 3 entries to represent the name of the country in 3 different languages. Following are the entity classes:
Country.java
@Entity
public class Country
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "COUNTRY_ID")
private long id;
@Column(name="COUNTRY_CODE", nullable = false, unique = true)
private String countryCode;
/*public getters*/
}
CountryDetail.java
@Entity
public class CountryDetail
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "COUNTRY_DETAIL_ID")
private long id;
@ManyToOne
@JoinColumn(name="COUNTRY_CODE", referencedColumnName = "COUNTRY_CODE")
private Country country;
@Column(nullable = false)
private String languageCode;
@Column(nullable = false, unique = true)
private String countryNameInLanguage;
/*public getters*/
}
My question is, how can I write a custom "findBy..." interface method inside an extension of JpaRepository that is typed to a Country
that would return me a collection of CountryDetail
elements that match an input parameter for the languageCode
attribute of the CountryDetail
class?
public interface CountryRepository extends JpaRepository<Country, Long>
I know how to do it if the repository was typed to CountryDetail
instead of Country
, but I would like to know how to do it going via the parent entity rather than via the child entity directly, even though the input parameter (languageCode
) exists only in the child entity.
Thank you.
Upvotes: 1
Views: 6010
Reputation: 5283
It is possible but complicated : Please see an example below :
Parent :
@Entity
@Table(name="PARENT")
public class Parent {
@Id
@Column(name="PARENT_ID")
private int parentId;
@Column(name="PARENT_NAME")
private String parentName;
@OneToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
private Child child;
}
Child :
@Entity
@Table(name="CHILD")
public class Child {
@Id
@Column(name="CHILD_ID")
private int childId;
@Column(name="CHILD_NAME")
private String childName;
@OneToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
private Parent parent;
}
Define an interface to load child entity from parent repository :
ChildEntity:
public interface ChildEntity {
@Value("#{target.child.childId}")
int getChildId() ;
@Value("#{target.child.childName}")
String getChildName();
}
Parent Repository :
public interface ParentRepository extends JpaRepository<Parent, Integer> {
public ChildEntity findByParentName(String parentName);
}
Test class:
ChildEntity chi=rep.findByParentName("<<NAME>>");
System.out.println(chi.getChildId()+" "+chi.getChildName());
Output:
CHILD ID 1000 CHILD NAME child1
Upvotes: 3