#Target({TYPE, ANNOTATION_TYPE, FIELD})
#Retention(RUNTIME)
#Constraint(validatedBy = {UniqueNameValidator.class})
#Documented
public #interface UniqueName {
String message() default "Unique name constraint";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class UniqueNameValidator implements ConstraintValidator<UniqueName, Object> {
#Override
public void initialize(UniqueName constraintAnnotation) {
System.out.println("UniqueNameValidator -> initialize() method invoked!");
}
#Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
System.out.println("UniqueNameValidator -> isValid method invoked!");
return true;
}
}
#Entity
public class MyClass implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID")
private Long id;
#UniqueName
#Column(name = "NAME")
private String name;
//Getters & Setters
}
The dependencies used in my project are :
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.2.18</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.2.18</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.6.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
Env :
Java 8
WebLogic Server: 12.2.1.2.0
Eclipselink version 2.6.4
After trying many suggestions from SOF i can't figure out why my custom validator is not called before persisting the entity (Validation on class level or field level) !
Any help will be appreciated.
I'm trying to save jsonb type data to a Postgres db table using the following library
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.11.1</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.14</version>
</dependency>
In java 8 it worked without any issue, But due to requirement I had to migrate the service to java 11 but after the migration when I tried to save jsonb to the table I got the following error.
org.springframework.orm.jpa.JpaSystemException: java.lang.IllegalArgumentException: The given byte array cannot be transformed to Json object; nested exception is org.hibernate.HibernateException: java.lang.IllegalArgumentException: The given byte array cannot be transformed to Json object.
NOTE - Hibernate versions are the same in both java 8 and java 11
version: 5.4.20.Final in both
Following is the entity which trying to save
#Builder(toBuilder = true)
#Data
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "test")
#TypeDefs({
#TypeDef(name = "jsonb", typeClass = JsonBinaryType.class),
})
public class Test extends Auditable {
#Id
#Column(name = "id", updatable = false, nullable = false, unique = true)
private UUID id;
#Type(type = "jsonb")
#Column(name = "data", columnDefinition = "jsonb")
private RequestEventDto data;
}
following is the RequestEventDto
import lombok.Builder;
import lombok.Data;
import java.util.List;
import java.util.Map;
#Data
#Builder
public class RequestEventDto {
private String requestId;
#Builder.Default
private String applicationId = "program1";
private String entityType;
private List<Map<String, Object>> listEntities;
}
Can you help with this problem?
Issue fixed with adding the following annotations to the RequestEventDto
#NoArgsConstructor
#AllArgsConstructor
public class RequestEventDto {
It seems it is due to the constructor not there when serialization happening.
I've got some trouble attempting to rebuild connection with Postgres server using Spring Boot (in Eclipse environment). Case-relevant entities look like:
1 - Specialization - web application I'm working provides with online registration for college athlete courses, so Specialization means gymnastics or sports any student can apply for upon his/her pleasure:
#Entity
#Table(name = "Specializations")
#Getter #Setter #NoArgsConstructor
public class Specialization {
#Id
#SequenceGenerator(name = "specialization_id_sequence", sequenceName = "specialization_id_sequence", allocationSize = 1, initialValue = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "specialization_id_sequence")
#Column(name = "id")
private Short id;
#Column(name="name")
private String name;
#ManyToOne
#JoinColumn(name="health_category_id", referencedColumnName = "id")
private HealthCategory category;
#Column(name="photo_file_path")
private String photoFilePath;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "specialization", cascade = CascadeType.ALL)
List <Trainer> trainerList;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "specialization", cascade = CascadeType.ALL)
List <Group> groupList;
//some hashCode() and equals() stuff here
#Override
public String toString() {
return "Specialization [id=" + id + ", name=" + name + ", min. approvable health category=" +
category.getId() + ", path=" + photoFilePath + "]";
}
2 - HealthCategory - prerequisite health class to be confirmed formally for getting admission to specialization-related engagement (different specilializations may be featured by the same health category required)
#Entity
#Table(name = "Health_categories")
#Getter #Setter #NoArgsConstructor
public class HealthCategory {
#Id
#SequenceGenerator(name = "category_id_sequence", sequenceName = "category_id_sequence", allocationSize = 1, initialValue = 1)
#GeneratedValue(strategy = GenerationType.IDENTITY, generator = "category_id_sequence")
#Column(name = "id")
private Short id;
#Column(name="name")
private String name;
#Column(name="state")
private Short state;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "category", cascade = CascadeType.ALL)
private List <Specialization> specialization;
#CreationTimestamp
#Temporal(TemporalType.TIMESTAMP)
#JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
#Column(name="last_update")
private Date last_update;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "category", cascade = CascadeType.ALL)
private List <User> userList;
#Override
public String toString() {
return "Health category [id=" + id + ", name=" + name + ", state=" + state + ", last update on=" + last_update + "]";
}
3 - Group - specialization-related group a student sign in to pass the course
#Entity
#Table(name = "Groups")
#Getter #Setter #NoArgsConstructor
public class Group {
#Id
#SequenceGenerator(name = "groupIdSequence", sequenceName = "groupIdSequence", allocationSize = 1, initialValue = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "groupIdSequence")
#Column(name = "group_id")
private Long group_id;
// eventual values: "open", "close"
#Column(name="registration_status")
private String registrationStatus;
// admission quota
#Column(name="target_size")
private Integer targetSize;
// real group size evaluation at the moment
#Column(name="actual_size")
private Integer actualSize;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "group", cascade = CascadeType.ALL)
private List <User> userList;
#ManyToOne
#JoinColumn(name="group_specialization_id", referencedColumnName = "id", nullable = false, unique = true)
private Specialization specialization;
#ManyToMany(cascade = { CascadeType.ALL })
#JoinTable(
name="schedules",
joinColumns = { #JoinColumn(name = "group_id") },
inverseJoinColumns = { #JoinColumn(name="schedule_id", nullable = false) })
private List<GroupSchedule> scheduleList;
#ManyToMany(mappedBy = "groupList")
private List<Trainer> trainerList;
#ManyToMany(cascade = { CascadeType.ALL })
#JoinTable(
name="locations",
joinColumns = { #JoinColumn(name = "group_id", nullable = false) },
inverseJoinColumns = { #JoinColumn(name="location_id", nullable = false) })
private List<Location> locationList;
#Column(name="description")
private String desciption;
4 - Trainer - an instructor concerned of holding lessons for respective groups of student who take specific course:
#Entity
#Table(name = "Trainers")
#Getter #Setter #NoArgsConstructor
public class Trainer {
#Id
#SequenceGenerator(name = "trainerIdSequence", sequenceName = "trainerIdSequence", allocationSize = 1, initialValue = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "trainerIdSequence")
#Column(name = "trainer_id")
private Short trainer_id;
#Column(name="first_name")
private String firstName;
#Column(name="second_name")
private String secondName;
#Column(name="last_name)")
private String lastName;
#Column(name="photo_file_path")
private String photoFilePath;
#ManyToOne
#JoinColumn(name="specialization_id", referencedColumnName = "id", nullable = false, unique = true)
private Specialization specialization;
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(
name="groups",
joinColumns = { #JoinColumn(name = "trainer_id", nullable = false) },
inverseJoinColumns = { #JoinColumn(name="group_id", nullable = false) })
private List<Group> groupList;
Because of difficulties when running code with Specialization objects, SpecializationService to be posted here:
#Service
public class SpecializationService {
#Autowired
private SpecializationRepository specializationRepository;
public SpecializationService(SpecializationRepository specializationRepository) {
this.specializationRepository = specializationRepository;
}
public void createSpecialization(Specialization specialization) {
specializationRepository.save(specialization);
}
public List<Specialization> findALL() {
return (List<Specialization>) specializationRepository.findAll();
}
public List<Specialization> getSpecializations() {
List<Specialization> specializations = new ArrayList<>();
specializationRepository.findAll().forEach(specializations::add);
return specializations;
}
}
SpecializationController code:
#RestController
public class SpecializationController {
#Autowired
SpecializationService specializationService;
#RequestMapping("/specialization")
public List<Specialization> getSpecializations() {
return specializationService.getSpecializations();
}
#RequestMapping(method = RequestMethod.POST, value = "/specialization/create")
public void createSpecialization(#RequestBody Specialization spec) {
specializationService.createSpecialization(spec);
}
}
Additively, there is relevant sql create table stuff:
CREATE SEQUENCE category_id_sequence;
CREATE TABLE Health_Categories (
id SMALLINT NOT NULL DEFAULT nextval('category_id_sequence') PRIMARY KEY,
name VARCHAR(30) DEFAULT NULL,
state SMALLINT NOT NULL,
last_update TIMESTAMP
);
-- Specialization --
CREATE SEQUENCE specialization_id_sequence;
CREATE TABLE Specializations (
id SMALLINT NOT NULL DEFAULT nextval('specialization_id_sequence') PRIMARY KEY,
name VARCHAR(50) DEFAULT NULL,
health_category_id SMALLINT REFERENCES health_categories (id),
photo_file_path VARCHAR(50) DEFAULT NULL,
CONSTRAINT specialization_ibfk_1 FOREIGN KEY (id) REFERENCES health_categories (id)
);
Once executing #SpringBootApplication class as follows:
#SpringBootApplication
public class DatabaseComponentsApplication {
#Autowired
private HealthCategoryService categoryService;
#Autowired
private SpecializationService specializationService;
public static void main(String[] args) {
SpringApplication.run(DatabaseComponentsApplication.class, args);
}
#EventListener(ApplicationReadyEvent.class)
private void testJpaMethods() {
HealthCategory cat2 = new HealthCategory();
Date date = new Date();
Timestamp ts = new Timestamp(date.getTime());
cat2.setLast_update(ts);
cat2.setName("Test2");
cat2.setSpecialization(null);
cat2.setState((short) 8);
categoryService.createCategory(cat2);
Specialization spec = new Specialization();
spec.setCategory(cat2);
spec.setName("Soccer");
spec.setPhotoFilePath(null);
specializationService.createSpecialization(spec);
specializationService.getSpecializations().forEach(it -> System.out.println(it));
}
}
it complains due to wrongness I still can't figure out to manage:
Caused by: org.postgresql.util.PSQLException: error: syntax error at or near: ")" Position: 209
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2505) ~[postgresql-42.2.9%20(1).jar:42.2.9]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2241) ~[postgresql-42.2.9%20(1).jar:42.2.9]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:310) ~[postgresql-42.2.9%20(1).jar:42.2.9]
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:447) ~[postgresql-42.2.9%20(1).jar:42.2.9]
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:368) ~[postgresql-42.2.9%20(1).jar:42.2.9]
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:158) ~[postgresql-42.2.9%20(1).jar:42.2.9]
at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:108) ~[postgresql-42.2.9%20(1).jar:42.2.9]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-3.4.1.jar:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-3.4.1.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
... 74 common frames omitted
Could you share your ideas what syntax issue causes that?
EDITED: pom.xml code as follows
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>databaseComponents</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>databaseComponents</name>
<description>DAO implementation draft </description>
<properties>
<java.version>1.8</java.version>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Also, application.properties stuff:
spring.datasource.driver=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/core_database
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.main.web-application-type=none
Is there any problem with calling findAll() method.
public List<Specialization> findAll() {
return (List<Specialization>) specializationRepository.findAll();
}
Can you replace getSpecializations() method
specializationService.getSpecializations().forEach(it -> System.out.println(it));
with findALL() method
specializationService.findALL().forEach(it -> System.out.println(it));
and see if it works ?
I'am new to micronaut and I try to follow this little project. However I would like it to work with postgres.
My application.yml looks like this:
micronaut:
application:
name: hello-world
datasources:
default:
url: 'jdbc:postgresql://localhost:5432/test'
username: test
password: test
driver-class-name: org.postgresql.Driver
jpa:
default:
properties:
hibernate:
hbm2ddl:
auto: update
show_sql: true
I have access to the database via intellij.
In the pom.xml I have the following dependencies:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.8</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.micronaut.configuration</groupId>
<artifactId>micronaut-jdbc-hikari</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.micronaut.configuration</groupId>
<artifactId>micronaut-hibernate-jpa</artifactId>
</dependency>
Additionally it is mentioned in the link that one needs annotionProcessor, so I added this to my build profile:
<annotationProcessorPaths>
<path>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</path>
</annotationProcessorPaths>
So now everytime I try to do the following:
#PersistenceContext
private EntityManager entityManager;
I get the following error:
Caused by: io.micronaut.context.exceptions.NoSuchBeanException: No bean of type [javax.persistence.EntityManager] exists. Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
However I already have annotation processing enabled. And I also have a #Entity-class:
#Entity
#Table(name = "users")
public class User {
#NotBlank
#Column(name = "name")
private String userName;
public User() {
}
public User(#NotBlank final String userName) {
this.userName = userName;
}
public String getUserName() {
return userName;
}
public void setUserName(final String userName) {
this.userName = userName;
}
}
What exactly am I missing in my setup?
There were multiple issues with my setup.
datasource and jpa need to be at root level
The #Entity needs a #Id
So in the end the application.yml looks like this:
micronaut:
application:
name: hello-world
datasources:
default:
url: 'jdbc:postgresql://localhost:5432/test'
username: test
password: test
driver-class-name: org.postgresql.Driver
jpa:
default:
packages-to-scan:
- 'test'
properties:
hibernate:
hbm2ddl:
auto: update
show_sql: true
And the #Entity-Class needs an #Id-Attribute:
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotBlank
#Column(name = "user_name")
private String userName;
public User() {
}
public User(#NotBlank final String userName) {
this.userName = userName;
}
public String getUserName() {
return userName;
}
public void setUserName(final String userName) {
this.userName = userName;
}
#Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
'}';
}
}
Like spring-data-jpa have #NotNull annotation what can be used for this in spring-data-mongodb.?
javax.validation.constraints.NotNull itself could be used with spring-data-mongodb. For this you need to have following in place.
JSR-303 dependencies added in your pom.xml
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.4.Final</version>
</dependency>
Declare appropriate validators and validator event listeners
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
#Configuration
public class Configuration {
#Bean
public ValidatingMongoEventListener validatingMongoEventListener() {
return new ValidatingMongoEventListener(validator());
}
#Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
}
Add #NotNull annotation in your MongoDB POJO
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import javax.validation.constraints.NotNull;
#Document(collection = "user_account")
public class User {
#Id
private String userId;
#NotNull(message = "User's first name must not be null")
private String firstName;
#NotNull(message = "User's last name must not be null")
private String lastName;
}
With this configuration and implementation, if you persist User object with null values, then you will see failure with javax.validation.ConstraintViolationException
Remember: if using #SpringBootApplication, make sure that Spring can scan your Configuration file. Otherwise, you may use #ComponentScan("com.mypackage").