12

While working on my first app in Hibernate. While trying to retrieve a User object from the DB i am getting the following exception:

org.hibernate.TypeMismatchException: Provided id of the wrong type for class org.cw.form.User. Expected: class java.lang.Integer, got class java.lang.String at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:109) at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:906) at org.hibernate.impl.SessionImpl.load(SessionImpl.java:823) at org.hibernate.impl.SessionImpl.load(SessionImpl.java:816)

I have created the USERS table with the following postgreSQL:

CREATE SEQUENCE user2_id_seq; 

CREATE TABLE USERS(id integer NOT NULL DEFAULT nextval('user2_id_seq'), user_name   varchar(45) NOT NULL UNIQUE , password varchar(45) NOT NULL, email varchar(45) NOT NULL, PRIMARY KEY (id));

And the User entity is defined as such:

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

@Id
@Column(name="ID")
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;

@Column(name="USER_NAME", unique = true)
private String userName;

@Column(name="PASSWORD")
private String password;

@Column(name="EMAIL")
private String email; .. all the getters and setters...

I am I missing something?

dkb
  • 4,389
  • 4
  • 36
  • 54
special0ne
  • 6,063
  • 17
  • 67
  • 107

7 Answers7

15

I had a different culprit creating this issue: I had copy-pasted another entity's repository which used a String as primary key type.

So I had

class MyEntity implements Serializable {

    @Id
    Integer id

in combination with

interface MyEntityRepository extends CrudRepository<MyEntity, String> {

which produced the error message.

Simply changing the interface type from String to Integer resolved the issue for me.

Jan Papenbrock
  • 1,037
  • 1
  • 11
  • 24
8

It would be easier to answer if you would show how do you retrieve Users. Based to message:

Provided id of the wrong type for class org.cw.form.User. 
Expected: class java.lang.Integer, got class java.lang.String

I guess you are providing String instead of correct type (Integer):

String userID = "1"; //Should be Integer userID = 1 instead
session.get(User.class, userID); 
Mikko Maunu
  • 41,366
  • 10
  • 132
  • 135
5

It often happens when you are going to perform one-to-one mapping with two entities that contain different types of primary keys in Spring JPA.

ex - you have two classes called user and laptop

User class

@Entity
class User{
   
    @Id
    private String userId;

    private String name;

 @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY,targetEntity = Laptop.class)
@JoinColumn(name = "USER_ID",referencedColumnName = "USER_ID")
 private Laptop laptop;

}

Laptop class

@Entity
class Laptop{

   @Id
   private int laptopId;

  private String brand;
}

how to overcome this issue

you can achieve it in 2 ways

  1. replace one-to-one relationship to one-to-many on the parent entity

    @Entity
     class User{
    
         @Id
         private String userId;
    
         private String name;
    
      @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,targetEntity = Laptop.class)
     @JoinColumn(name = "USER_ID",referencedColumnName = "USER_ID")
      private Laptop laptop;
    
     }
    
  2. you can perform one-to-one relationship on the child entity

  @Entity
class Laptop{

   @Id
   private int laptopId;

   private String brand;

   @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER,targetEntity = 
    User.class)
    @JoinColumn(name = "USER_ID",referencedColumnName = "USER_ID")
     private User user;

}
Nafaz M N M
  • 1,558
  • 2
  • 27
  • 41
  • Why does the wrong type mismatch go away when you switch it to one-to-many. It works, I just tried it, but not sure why this works the way it does. – qHack Jan 14 '22 at 08:09
4
public User findClientByUsername(String login) {        
        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(User.class);
        criteria.add(Restrictions.like("userName", login));
        return (User) criteria.uniqueResult();
    }

Solution of your problem.

HelterShelter
  • 171
  • 2
  • 11
4

I don't really know if it'll solve your issue, but since you are using sequences to generate ids on the db side, I think you should use a Sequence generator :

@Id
@Column(name="ID")
@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="user2_id_seq")
private Integer id;

Please see this post for details : Hibernate sequence on oracle, @GeneratedValue(strategy = GenerationType.AUTO)

Community
  • 1
  • 1
ndeverge
  • 21,378
  • 4
  • 56
  • 85
1

I also had the same issue, If you have made id as autoincrement then it doesn't require any setters, only get is fine as mentioned below.

  public Long getId() {
       return id;
   }
Brahmadev
  • 49
  • 1
  • 10
1

I got this problem, when I tried to use inheritance for the identifier class (@IdClass).

Spille
  • 527
  • 4
  • 12