Entity retrieved from database with same case as in query

malhobayyeb :

My database contains the following table:

table:

country {
    code varchar(255) not null
        primary key
};

class:

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

    public String getCode() {
        return mCode;
    }

    public void setCode(String code) {
        mCode = code;
    }
}

sample table rows:

| code |
|------|
| USA  |
| UK   |

When I retrieve a country using the following CrudRepository:

public interface CountryRepository extends CrudRepository<Country, String> {
}

First scenario:

mRepository.findOne("USA")

It will give me the following result in my rest api:

{
  "code": "USA"
}

Second scenario:

mRepository.findOne("UsA")

It will give me the following result in my rest api:

{
  "code": "UsA"
}

Third scenario:

mRepository.findOne("Usa")

It will give me the following result in my rest api:

{
  "code": "Usa"
}

I have also inspected the same behavior using the debugger and found my object in memory actually have the same behavior.

What I Want: I want the returned data to be the same case as in database.

Dragan Bozanovic :

As already hinted by @Bedla in the comment, you may be using a case insensitive varchar data type in your database. However, this is not recommended for primary keys in Hibernate (and in general), because Hibernate relies on id property value uniqueness when referring to entities in the persistence context (and second-level cache if enabled).

For example, after loading an entity by "USA" and then by "usa" (or after merging a detached "usa" while "USA" has already been loaded, etc) in the same persistence context you may end up with two different instances in the persistence context, meaning further that they would be flushed separately thus overwriting each other changes, etc.

Rather use a case sensitive data type in the database, but allow searching by ignoring case:

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

PS Country codes are not good candidates for primary keys in general, because they can change.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=470203&siteId=1