简体   繁体   中英

Conditional load of relations using spring data jpa

I'm developing a multi language application and My tables are designed for this purpose as well. for example I have a Country class like this:

@Entity
@Table(name = "province")
public class Province {

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

    @ManyToOne
    @JoinColumn(name = "country_id", nullable = false)
    private Country country;

    @OneToMany
    @JoinColumn(name = "province_id")
    private List<ProvinceTranslation> translations;
}

@Entity
@Table(name = "province_translation")
public class ProvinceTranslation {

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

    private String name;

    private Language language;

    @ManyToOne
    @JoinColumn(name = "province_id")
    private Province province;
}

I want that translations field load only translation with specified language, and country field load translation with specified language too( Country class has a list of CountryTranslation obviously!). I don't want to write queries and I want that spring data jpa load relations with the language that I specify explicitly.

It seems, a little bit of writing JPA query is required in this case.

Because the countryTranslation class is missing I put the focus on the Province class.

The Language class is also unknown, maybe this is an enum one, like this:

public enum Language {UNKNOWN, GERMAN, ENGLISH, SPAIN}

To avoid loading of all translations of the entity you have to select the translation according to the given language while fetching the entities from database. I prefer to do this with utilizing spring repositories (which I hope you already have involved). In the ProvinceRepository declared like this

    public interface ProvinceRepository extends CrudRepository<Province, Long> {
    ...
    }

you have to provide the required find- or count methods.

To get a List of all provinces with specific translation you may declare a function like this one, inside the ProvinceRepository :

    @Query("SELECT new org.your.package.goes.here.Province(p.id, p.country, pt.name) FROM Province p inner join p.translations pt where pt.language = ?1")
    List<Province> findAllWithTranslation(Language language);

To make this working, there must a exist a constuctor that accepts the three parameters id, country, name . The name parameter may be set to a new translation property of the Province class, respectively the created province object. If the Language class is indeed an enum class the @Enumerated annotation must be added to the language field.

Nevertheless, I am convinced that the provision of translation strings should be better done with the help of an internationalization library (i18n).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM