Announcement Announcement Module
Collapse
No announcement yet.
How to reuse the super repositories persistent logic with different entity type Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to reuse the super repositories persistent logic with different entity type

    Assume i have an application which will deal with 3 regions, Such as: China, India and Korea. And the 3 regions has similar table to persistent, but each table may has it's specific fields (even more for the history reason, the table has different table name), So take an example (User table)


    here as follows:


    China has: China_User_Table
    India has: India_User_Table
    Korea has: Korea_User_Table


    The above tables has different table name, and also have both some samefields (such as: id, name) and specific fields (such as street).


    So based on the above requirement, I created 4 Class:
    1: AbstractUserEntity (it is abstract class, do not map to any table)
    2: UserKoreaEntity (extends from AbstractUserEntity, map to Korea_User_Table)
    2: UserIndiaEntity (extends from AbstractUserEntity, map to India_User_Table)
    3: UserChinaEntity (extends from AbstractUserEntity, map to China_User_Table)


    See code as below:


    @MappedSuperclass
    public abstract class AbstractUserEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;
    private String country;
    private String address;
    private int age;
    private String friend;

    ....getters, setters
    }

    @Entity
    @Table(name = "China_User_Table")
    public class UserChinaEntity extends AbstractUserEntity {

    private String street;

    ...setters, getters.
    }

    @Entity
    @Table(name = "India_User_Table")
    public class UserIndiaEntity extends AbstractUserEntity {

    }


    @Entity
    @Table(name = "Korea_User_Table")
    public class UserKoreaEntity extends AbstractUserEntity {

    @Column(name = "myHouse")
    private String house;

    ...setters, getters
    }

    Although the China, Korea and India has it's specific entity, but the China and India has the same

    persistent logic, and Korea has some same persistent logic , and some others not same.


    So i build 2 repository class.
    1: common repository for China and India to handle the same logic
    2: Korea repository extends from the common repository so the same logic can reuse the common repository method, and also override some method for the different logic.

    1: UserCommonRepo (deal with China and India logic)
    2: UserKoreaRepo (deal with korea logic)

    public interface UserCommonRepo <T extends AbstractUserEntity > extends
    CrudRepository <T, Long> {

    public AbstractUserEntity findByUserId(int id);

    @Query("SELECT u FROM UserChinaEntity u WHERE u.name = ?1")
    public AbstractUserEntity findByUserName(String name);

    @Modifying
    @Query("UPDATE UserChinaEntity u set u.address = ?2 where u.id = ?1")
    public int changeAddressById(int id, String address);

    }

    public interface UserKoreaRepo extends UserCommonRepo<UserKoreaEntity>{

    //override the UserCommonRepo method
    @Modifying
    @Query("UPDATE UserKoreaEntity u set u.address = ?2, u.country = ?2 where u.id = ?1")
    public int changeAddressById(int id, String address);

    }

    I want to reuse the same persistence logic for different regions, so i created UserCommonRepo

    So my question as follows:

    1: UserCommonRepo's generic type for entity is AbstractUserEntity(this is not really an entity), and spring will build the userCommonRepo bean in it's application context automatically based on the AbstractUserEntity. So how can i tell spring to build 2 userCommonRepo beans, 1 bean based on UserChinaEntity, 1 bean based on UserIndiaEntity (because the china and india have the same persistent logic).


    2: The logic of "findByUserId" will suit for both China and India in UserCommonRepo, but how can ensure when the region is China, it can select from china table, and the same as for India, how ensure to select from India when the region is India.


    3: The logic of "findByUserName" for UserCommonRepo has it's own query string by @Query annotation, but in this JPQL query string, i can not select from AbstractUserEntity, so i use the UserChinaEntity as default, so when i want to select from India region, how i can change the statement from ("SELECT u FROM UserChinaEntity u WHERE u.name = ?1") to ("SELECT u FROM UserIndiaEntity u WHERE u.name = ?1") dynamically?


    4: The same as question 2 when it happens to UserKoreaRepo, because it extends from UserCommonRepo, How i can change the statement to UserKoreaEntity ("SELECT u FROM UserKoreaEntity u WHERE u.name = ?1") when the customer invoke the "findByUserName" method in UserKoreaRepo?


    5: For the @Query annotation, it can just take the constant as parameter, is there some way can set the variable into @Query annotation?


    6: Is there some like Listener or Filter in spring data jpa that i can use to change the JPQL dynamically?
Working...
X