2

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.

Nariman Esmaiely Fard
  • 505
  • 1
  • 10
  • 24
  • I think you could add [Entity graphs](https://stackoverflow.com/questions/31943989/spring-data-jpa-and-namedentitygraphs) to Province entity and add country and provinceTranslation but you still missed countryTranslation so my recommendation is use a native query that would be more flexible and fit easier than jpa to this requirement – peterzinho16 Jul 21 '19 at 20:27

1 Answers1

1

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).

Mike Feustel
  • 1,277
  • 5
  • 14