1

I am using Spring Data Jpa with a legacy Oracle database. Some of our tables used char instead of varchar2 type. That causes some issue when I am using Spring Data Jpa generated query.

For example, I have an entity which named User

@Entity
@Table(name = "USERS")
public class User implements Serializable {

    private static final long serialVersionUID = -4054737587007197812L;

    @Id
    private Long userId;
    @Column(columnDefinition = "char", length = 12)
    private String username;
}

My UserRepository is like:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    public User findByUsername(String name);
}

As usual, the Spring Data will generate a query like select * from users where username = ?. But since my Oracle database is using char type for column username, I will not get any result if I passed in the username parameter without padding enough space.

userRepository.findByUsername("Chris") -> not result
userRepository.findByUsername("Chris[with 7 spaces]") -> 1 result

Is there anyway to add some custom code to Spring Data Jpa and let Spring Data Jpa pads the spaces automatically? I don't want to write all query method again and pad the space manually since I have added the length in the Entity class ().

1
  • I can't think of a way to do this in JPA because you would probably have columns of different sizes. If you are using Hibernate, this could be achieved using user types. Commented Feb 25, 2015 at 15:58

1 Answer 1

1

If you are using Hibernate as the JPA provider, this can be achieved by creating a Hibernate UserType.

  1. Create a custom user type called CharType. Perform the necessary padding and trimming within this class.
  2. Annotate fields with CHAR(n) as the backing datatype to use CharType.

A complete solution, along with the CharType class is available on Github. See the Person entity and test cases in PersonRepositoryTest for guidance on how to integrate something like this in your own code.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot. It works. But only for ojdbc7. ojdbc6 doesn't support ParameterMetaData.getPrecision(index) method.
Besides, I have another issue. If I update grade to ojdbc7. I have ORA-00942: table or view does not exist error. I am using Spring Boot now and I have set the spring.jpa.properties.hibernate.default_schema=my_oracle_username
For some reason OJDBC6 does not implement most of the ParameterMetaData methods. This is not a deficiency in the Hibernate UserType solution but utter disregard for end-user requirements and JDBC spec on part of Oracle so there isn't much we can do. My experience with the Oracle drivers has been to set the schema name in the JDBC URL as jdbc:oracle:thin:<schema>@//<server:<port>/<tnslistener> instead of setting the schema name for the JPA provider. Make sure you are not setting the schema name in both places as the driver will then prefix table names with the schema name twice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.