简体   繁体   中英

Composite Id JPA2 and Spring Data not working

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.

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