Exception trying convert UUID attribute (foreign key) to Entity object - java

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

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.

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

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;

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.

Related

Column doesn`t exist

Try to learn hibernate + jpa, don`t know what to do with this. Error when getting by id.
JDBC exception executing SQL [select u1_0.id,u1_0.email,u1_0.login,u1_0.password,r1_0.id,r1_0.name from user u1_0 left join role r1_0 on r1_0.id=u1_0.role_id where u1_0.id=?]
Caused by: org.postgresql.util.PSQLException: ERROR: column u1_0.role_id doesn`t exist
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(nullable = false, unique = true)
private String login;
#Column(nullable = false)
private String password;
#Column(nullable = false, unique = true)
private String email;
#ManyToOne
#JoinColumn(name = "role_id")
private UserRole role;
}
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Entity
#Table(name = "role")
public class UserRole {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(nullable = false)
private String name;
}
enter image description here
Tried to debug but no results

How to create a JPA entity which has a field(s) from another entity?

I have the following entity in SpringBoot and I would like to create a new entity which has the userID of the registered user and the name of the registered/logged in user as instance fields/table columns.
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name="User")
public class WebUser {
#Id
#GeneratedValue
private Long userID;
#NonNull
private String name;
#NonNull
private String email;
#NonNull
private String password;
}
How would I go about doing this using a form in SpringBoot and JPA entity? I am struggling, I tried to create a form with hidden input fields using #OneToMany annotation but the userID and name were null.
Thanks for any help
Frist of all you Should define table column names using #Column(name = "COLUMN_NAME") and assume your new entity name LogUser.
LogUser
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name="LogUser")
public class LogUser{
#Id
#GeneratedValue
#Column(name = "ID")
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "USER_ID", nullable = false)
private WebUser webUser;
#Column(name = "NAME", nullable = false)
private String name;
}
WebUser
#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name="User")
public class WebUser {
#Id
#GeneratedValue
#Column(name = "USER_ID")
private Long userID;
#Column(name = "NAME", nullable = false)
private String name;
#Column(name = "EMAIL", nullable = false)
private String email;
#Column(name = "PASSWORD", nullable = false)
private String password;
#OneToMany(mappedBy = "webUser")
private Set<LogUser> logUsers;
}

Null point exception on set spring JPA relationship

I have already seen topics with this question, but they did not help me. Maybe I didn't see something.
Below I attach the code and the error.
#Entity
#Table(name = "department")
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#EqualsAndHashCode
public class Department {
#Id
#GenericGenerator(name = "uuid2", strategy = "uuid2")
#GeneratedValue(strategy = GenerationType.IDENTITY, generator = "uuid2")
#Column(length = 36, nullable = false, updatable = false)
private UUID id;
#Column(name = "name", nullable = false)
private String name;
#Column(name = "description", nullable = false)
private String description;
#OneToMany(mappedBy = "department", cascade = CascadeType.ALL, fetch = FetchType.LAZY,
orphanRemoval = true)
private Set<User> userSet = new HashSet<>();
}
AND user
#Entity
#Table(name = "user")
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#EqualsAndHashCode
public class User {
#Id
#GenericGenerator(name = "uuid2", strategy = "uuid2")
#GeneratedValue(strategy = GenerationType.IDENTITY, generator = "uuid2")
#Column(length = 36, nullable = false, updatable = false)
private UUID id;
private String firstName;
private String lastName;
private Integer age;
#ManyToOne
#JoinColumn(name = "dep_id", nullable = true)
private Department department;
#ManyToMany
#JoinTable(
name = "device_devices",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "device_id"))
Set<Device> devices = new HashSet<>();
}
and service
#Override
public List<DepartmentDto> getAllDepartment() {
List<Department> all = departmentRepository.findAll();
return all.stream().map(mapper::toDepartmentDto).collect(Collectors.toList());
}
#Override
public UUID createDepartment(DepartmentDto departmentDto) {
Department entity = mapper.DtoToDepartment(departmentDto);
return departmentRepository.save(entity).getId();
}
#Override
public void deleteDepartment(UUID id) {
departmentRepository.deleteById(id);
}
#Override
#Transactional
public void addUserToDepartment(UUID departmentId,UUID userId){
Department department = departmentRepository.findById(departmentId).orElseThrow(DepartmentNotFoundException::new);
User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new);
department.getUserSet().add(user); // ERROR java.lang.NullPointerException: null
user.setDepartment(department);
}
I think I did something wrong. I tried writing Cascade.ALL but it didn't help me. I don't think I fully understand the concept of a link collection yet. I don't like that in my code, I add the user to the department, and then I add the department to the user. Probably it can be done in one action.
Task.
I want to make a department and 2 functions. Add a user to the department and remove users from the department. in such a way that the contempt of the users from the department the user himself was not removed.
I will be glad to hear your comments
if you use #Builder annotation on top of the class
and you want to set default value for a field,
you must put annotation #Builder.Default on top of field
#Builder.Default
Set<Device> devices = new HashSet<>();
otherwise devices will always be NULL when the builder builds the object

Unable to use #NamedEntityGraph with #ElementCollecion

I'm trying to set simple entity with NamedEntityGraph on it. Unfortunately it won't work. Could you have any ideas how to fix it?
ServiceType entity has #ElementCollection of with Set of String which are simply ids of PictureModel associated with entity. On run I got:
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [backgroundPicIds] on this ManagedType [pl.mihome.djcost.model.ServiceType]
#Entity
#Table(name = "service_type")
#Getter
#Setter
#NoArgsConstructor
#NamedEntityGraph(
name = "serviceType.with.backgroundPicIds",
attributeNodes = #NamedAttributeNode("backgroundPicIds")
)
public class ServiceType {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Setter(AccessLevel.NONE)
#Column(nullable = false, updatable = false)
private int id;
#Length(max = 100)
#NotBlank
private String name;
private boolean active;
#OneToMany(mappedBy = "serviceType")
private Set<Account> accounts;
#ManyToMany(mappedBy = "servicesApplicable")
private Set<AccountType> accountTypes;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "serviceType", orphanRemoval = true, cascade = CascadeType.ALL)
private Set<PictureModel> backgroundPicture;
#ElementCollection
#CollectionTable(name = "image", joinColumns = {#JoinColumn(name = "service_type_id")})
#Column(name = "id")
private Set<String> backgroundPictureId;
#PrePersist
void activate() {
this.active = true;
}
}
#Entity
#Table(name = "image")
#NoArgsConstructor
#Getter
#Setter
#Builder
#AllArgsConstructor
public class PictureModel {
#Id
#GeneratedValue(generator = "UUID")
#GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
#Column(nullable = false, updatable = false)
#Setter(AccessLevel.NONE)
private String id;
private String type;
private String name;
#Lob
private byte[] body;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "account_id")
private Account account;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "public_platform_id")
private PublicPlatform publicPlatform;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "service_type_id")
private ServiceType serviceType;
}
You simply do not have an attribute with the name backgroundPicIds in the entity ServiceType.
Try to correct your graph in this way:
#NamedEntityGraph(
name = "serviceType.with.backgroundPicIds",
attributeNodes = #NamedAttributeNode("backgroundPictureId")
)

JdbcSQLSyntaxErrorException: Syntax error in SQL statement "DROP TABLE PUBLIC.PRODUCTS-[*]USERS IF EXISTS "

I'm trying to write tests and using in memory DB. My problem is to create schema for tests from hibernate entities.
I have such entities
#Entity
#Table(name = "users", schema = "public")
#Getter
#Setter
#NoArgsConstructor
public class User {
#Id
#Column(name = "user_id", updatable = false, nullable = false, unique = true)
#GeneratedValue(generator = "UUID")
#GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;
#Column(name = "name")
private String name;
#Column(name = "product")
#ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
#JoinTable(name = "products_users",
joinColumns = {#JoinColumn(name = "user_id")},
inverseJoinColumns = {#JoinColumn(name = "product_id")})
private Set<Product> products;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd#HH:mm:ss")
#Column(name = "created_on")
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private Date createdOn;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd#HH:mm:ss")
#Column(name = "modified_on")
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private Date modifiedOn;
public User(String name, Set<Product> products, Date createdOn, Date modifiedOn) {
this.name = name;
this.products = products;
this.createdOn = createdOn;
this.modifiedOn = modifiedOn;
}
}
#Entity
#Table(name = "product", schema = "public")
#Getter
#Setter
#NoArgsConstructor
public class Product {
#Id
#Column(name = "product_id", updatable = false, nullable = false, unique = true)
#GeneratedValue(generator = "UUID")
#GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;
#Column(name = "name")
private String name;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd#HH:mm:ss")
#Column(name = "created_on")
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private Date createdOn;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd#HH:mm:ss")
#Column(name = "modified_on")
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private Date modifiedOn;
public Product(String name, Date createdOn, Date modifiedOn) {
this.name = name;
this.createdOn = createdOn;
this.modifiedOn = modifiedOn;
}
}
#Entity
#Table(name = "products_users", schema = "public")
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class ProductsUsers {
#Id
#Column(name = "user_id", updatable = false, nullable = false, unique = true)
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private UUID userId;
#Column(name = "product_id")
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private UUID productId;
}
and
application.properties
spring.output.ansi.enabled=ALWAYS
server.port=8081
debug=true
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=123
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=false
And I have
application.properties
in tests package
spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS public;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
spring.jpa.properties.hibernate.default_schema=public
And I get such exception
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error
executing DDL "alter table "public"."products_users" drop constraint
"FK2w1ylwiyjuy67n1ycr5lv5or3"" via JDBC Statement
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table
"products_users" not found; SQL statement: alter table
"public"."products_users" drop constraint
"FK2w1ylwiyjuy67n1ycr5lv5or3"

Categories