I had the following entity mapped using JPA 2:
@Entity
public class Translation {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;
private String locale;
@Column(name = "business_code",insertable = true,updatable = false,length = 200,nullable = false)
private String code;
private String text;
// Gettets and setters
....
}
Then I realized than the pair (locale,code) should be unique, so I have changed the entity to have an embeddedId composed by locale, code and I removed the column id from the mapping. This way this pair would act as primary key and they could not be repeated:
As a result:
@Entity
public class Translation {
@EmbeddedId
private TranslationId translationId;
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public TranslationId getTranslationId() {
return translationId;
}
public void setTranslationId(TranslationId translationId) {
this.translationId = translationId;
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}
And the embeddedId class:
@Embeddable
public class TranslationId implements Serializable{
private static final long serialVersionUID = 1L;
private String locale;
@Column(name = "business_code",insertable = true,updatable = false,length = 200,nullable = false)
private String code;
@Override
public boolean equals(Object obj){
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public int hashCode(){
return HashCodeBuilder.reflectionHashCode(this);
}
public String getLocale() {
return locale;
}
public void setLocale(String locale) {
this.locale = locale;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
I'm using Spring data to query the data, so I have modified also my JPA repository to take in account the new composite Id:
@Repository
public interface TranslationRepository extends JpaRepository<Translation,TranslationId> {
}
So, first of all, does anyone see anything wrong here? Should I do it in another way? As my tests are not passing anymore, if I do a simple translationRepository.findAll()
, I'm not getting any result (however there is data in the db), but I'm not getting any error message...
And second - if I get this to work, and then I want Spring data to query all the translations only by locale (not by code), how can I do it? As locale and code are now part of the primary key, can I query them independently?
Since your first problem was already fixed, I'll answer the second question
I want Spring data to query all the translations only by locale (not by code), how can I do it?
locale
is still accessible as a single property via translationId
. In JPQL you can write
SELECT t FROM Translation t WHERE t.translationId.locale = :locale
In Spring Data repository you can either use the @Query
on a custom-named method
@Query("SELECT t FROM Translation t WHERE t.translationId.locale = :locale")
public List<Translation> findByLocale(@Param("locale") String locale)
or go with the slightly longer method name, but automatically handled by Spring Data
public List<Translation> findByTranslationIdLocale(String locale)
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.