从数据库中检索的实体与查询中的情况相同

mal*_*yeb 6 java spring hibernate spring-data-jpa

我的数据库包含下表:

表:

country {
    code varchar(255) not null
        primary key
};
Run Code Online (Sandbox Code Playgroud)

类:

@Entity
public class Country {
    @Id
    @Column(name = "code")
    private String mCode;

    public String getCode() {
        return mCode;
    }

    public void setCode(String code) {
        mCode = code;
    }
}
Run Code Online (Sandbox Code Playgroud)

样本表行:

| code |
|------|
| USA  |
| UK   |
Run Code Online (Sandbox Code Playgroud)

当我使用以下CrudRepository检索国家/地区时:

public interface CountryRepository extends CrudRepository<Country, String> {
}
Run Code Online (Sandbox Code Playgroud)

第一种情况:

mRepository.findOne("USA")
Run Code Online (Sandbox Code Playgroud)

它将在我的休息api中给出以下结果:

{
  "code": "USA"
}
Run Code Online (Sandbox Code Playgroud)

第二种情况:

mRepository.findOne("UsA")
Run Code Online (Sandbox Code Playgroud)

它将在我的休息api中给出以下结果:

{
  "code": "UsA"
}
Run Code Online (Sandbox Code Playgroud)

第三种情况:

mRepository.findOne("Usa")
Run Code Online (Sandbox Code Playgroud)

它将在我的休息api中给出以下结果:

{
  "code": "Usa"
}
Run Code Online (Sandbox Code Playgroud)

我还使用调试器检查了相同的行为,发现我在内存中的对象实际上具有相同的行为.

我想要的:我希望返回的数据与数据库中的数据相同.

Dra*_*vic 7

正如@Bedla在评论中已经暗示的那样,您可能在数据库中使用不区分大小写的varchar数据类型.但是,这不建议用于Hibernate中的主键(通常),因为Hibernate在引用持久化上下文中的实体(如果启用了二级缓存)时依赖于id属性值唯一性.

例如,通过加载的实体之后"USA",然后通过"usa"(或合并一个分离之后"usa""USA"已经被加载,等等)在相同的持久化上下文你可能最终与持久性上下文两个不同的情况下,进一步,他们将被刷新意分别因此覆盖彼此的变化等

而是在数据库中使用区分大小写的数据类型,但允许通过忽略大小写进行搜索:

public interface CountryRepository extends CrudRepository<Country, String> {
    @Query("select c from Country c where upper(c.mCode) = upper(?1)")
    Country getCountry(String code);
}
Run Code Online (Sandbox Code Playgroud)

PS国家/地区代码一般不适合主键,因为它们可以更改.