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.