ITWorker
ITWorker

Reputation: 995

How to write a Repository method for a parent entity that returns child entities?

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

Answers (1)

Barath
Barath

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

Related Questions