'Exception trying convert UUID attribute (foreign key) to Entity object
I am developing a spring-boot application (jpa...etc), and I am stuck in one problem. I am using the UUID attribute for the primary keys. When I try to create object as foreign key, the jpa can't cast correctly to my object.
I tried to use a AttributeConverter, but jpa does not call it.
My UserEntity
@Entity(name = "User")
@Table(name = "USR")
@EntityListeners(UserPersistListener.class)
@EqualsAndHashCode
public class UserEntity {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "ID", updatable = false)
@Getter
@Setter
private String id;
@Column(name = "LOGIN", updatable = false)
@Getter
@Setter
private String login;
@Column(name = "PASS")
@Getter
@Setter
private String pass;
@Enumerated(EnumType.STRING)
@Column(name = "ROLE")
@Getter
@Setter
private Role role;
}
My other Entity Person using UserEntity (foreign key)
@Entity(name = "Person")
@Table(name = "PERSON")
@EqualsAndHashCode
public class PersonEntity {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "ID", updatable = false)
@Getter
@Setter
private String id;
@Column(name = "NAME")
@Getter
@Setter
private String name;
@Column(name = "SUBSCRIPTION")
@Getter
@Setter
private Long subscription;
@Enumerated(EnumType.STRING)
@Column(name = "SUBSCRIPTION_TYPE")
@Getter
@Setter
private SubscriptionType subscriptionType;
@Column(name = "PHONE1")
@Getter
@Setter
private Long phone1;
@Column(name = "PHONE2")
@Getter
@Setter
private Long phone2;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CREATED_BY", updatable = false)
@Getter
@Setter
private UserEntity createdBy;
@Convert(converter = LocalDateAttributeConverter.class)
@Column(name = "CREATION_DATE")
@Getter
@Setter
private LocalDateTime creationDate;
}
Exception
org.springframework.data.domain.PageImpl["content"]->java.util.Collections$UnmodifiableRandomAccessList[0]->br.com.orangesun.entity.person.PersonEntity["createdBy"]->br.com.orangesun.entity.user.UserEntity_$$_jvst424_1["id"])
2019-06-18 00:52:55.163 WARN 15432 --- [nio-8099-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42883
2019-06-18 00:52:55.164 ERROR 15432 --- [nio-8099-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: operator does not exist: uuid = character varying
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
Edit
My database definition
| Field Name | Type |
|-----------------------------|
| id | uuid |
| name | varchar |
| subscription | int8 |
| subscription_type | varchar |
| created_by | uuid |
| creation_date | instant |
| phone1 | int8 |
| phone2 | int8 |
|-----------------------------|
EDIT 2
Other details about same error
java.lang.IllegalArgumentException: Provided id of the wrong type for class br.com.orangesun.entity.person.PersonEntity. Expected: class java.lang.String, got class java.util.UUID
Solution 1:[1]
Try to use UUID type instead of String for 'id' fields, because UUID is a binary format, not character based, so databases use special type for UUID fields.
Solution 2:[2]
Update your PersonEntity class as below,
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CREATED_BY", referencedColumnName = "ID”, updatable = false)
@Getter
@Setter
private UserEntity createdBy;
Add referencedColumnName to your @joinColumn
Solution 3:[3]
UUID in Postgres is automatically converted for you into UUID datatype. You must change your id datatype from String to UUID and everything will work as expected.
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "ID", updatable = false)
@Getter
@Setter
private UUID id;
Solution 4:[4]
Use UUID instead of String.
Moreover, replace
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CREATED_BY", updatable = false)
by
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CREATED_BY", referencedColumnName = "ID", updatable = false)
It gives:
The UserEntity:
@Entity(name = "User")
@Table(name = "USR")
@EntityListeners(UserPersistListener.class)
@EqualsAndHashCode
public class UserEntity {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "ID", updatable = false)
@Getter
@Setter
private UUID id;
@Column(name = "LOGIN", updatable = false)
@Getter
@Setter
private String login;
@Column(name = "PASS")
@Getter
@Setter
private String pass;
@Enumerated(EnumType.STRING)
@Column(name = "ROLE")
@Getter
@Setter
private Role role;
}
The other Entity Person using UserEntity (foreign key)
@Entity(name = "Person")
@Table(name = "PERSON")
@EqualsAndHashCode
public class PersonEntity {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "ID", updatable = false)
@Getter
@Setter
private UUID id;
@Column(name = "NAME")
@Getter
@Setter
private String name;
@Column(name = "SUBSCRIPTION")
@Getter
@Setter
private Long subscription;
@Enumerated(EnumType.STRING)
@Column(name = "SUBSCRIPTION_TYPE")
@Getter
@Setter
private SubscriptionType subscriptionType;
@Column(name = "PHONE1")
@Getter
@Setter
private Long phone1;
@Column(name = "PHONE2")
@Getter
@Setter
private Long phone2;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CREATED_BY", referencedColumnName = "ID", updatable = false)
@Getter
@Setter
private UserEntity createdBy;
@Convert(converter = LocalDateAttributeConverter.class)
@Column(name = "CREATION_DATE")
@Getter
@Setter
private LocalDateTime creationDate;
}
as per OP gmrosa's own prior edit to the question.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ivan Rasikhin |
| Solution 2 | Tarun Jain |
| Solution 3 | Alan Sereb |
| Solution 4 | vinzee |
