Postgresql jsonb doesn't work with Spring Data JPA - postgresql

I tried to save into a jsonb column but I didn't find any solution of my problem.
Postgresql 15.
This is the mapping class
#Getter
#Setter
#NoArgsConstructor
#Entity(name = "template")
#Table(name = "template")
public class Template {
#Id
#Column(name = "ID")
private UUID id;
#Column(name = "name")
private String name;
#Column(name = "version")
private Integer version;
#Convert(converter = TemplateFullConverter.class)
#Column(name = "tbody")
private TemplateFull tbody;
}
With the following TemplateFullConverter class
#Converter
public class TemplateFullConverter implements AttributeConverter<TemplateFull, PGobject> {
Logger logger = LoggerFactory.getLogger(this.getClass());
#Override
public PGobject convertToDatabaseColumn(TemplateFull templateFull) {
final PGobject po = new PGobject();
po.setType("jsonb");
try {
po.setValue(JsonHelper.fromModelToString(templateFull));
} catch (SQLException | JsonProcessingException e) {
logger.error("Cannot convert TemplateFull to PGobject");
throw new RuntimeException(e);
}
return po;
}
#Override
public TemplateFull convertToEntityAttribute(PGobject pGobject) {
if (pGobject == null || pGobject.getValue() == null) {
return null;
}
try {
return JsonHelper.fromStringToModel(pGobject.getValue(), TemplateFull.class);
} catch (IOException e) {
logger.error("Cannot convert PGobject to TemplateFull");
throw new RuntimeException(e);
}
}
}
This is the pom:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
During the save, there is the following error:
org.postgresql.util.PSQLException: ERROR: column "tbody" is of type jsonb but expression is of type bytea
Hint: You will need to rewrite or cast the expression.
Position: 117
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2676) ~[postgresql-42.5.3.jar:42.5.3]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2366) ~[postgresql-42.5.3.jar:42.5.3]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:356) ~[postgresql-42.5.3.jar:42.5.3]
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:496) ~[postgresql-42.5.3.jar:42.5.3]
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:413) ~[postgresql-42.5.3.jar:42.5.3]
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:190) ~[postgresql-42.5.3.jar:42.5.3]
at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:152) ~[postgresql-42.5.3.jar:42.5.3]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-5.0.1.jar:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-5.0.1.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:39) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3423) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:4058) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:103) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:612) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:483) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:480) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:329) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
I'm expecting the save correctly save into the table but there is a problem.
Any help is appreciated!

Related

Custom ConstraintValidator not invoked before persist

#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.

Spring Data JPA Primary Key Violation Constraint Not Working

Code and Configuration :
DB used - H2 in Memory database
User Entity :
#Entity
#Table(name = "users")
#Data
#AllArgsConstructor
#NoArgsConstructor
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 455202739064202185L;
#Id // please note is not auto generated but manually generated
#Column(name = "id",unique=true)
#NotNull
private long id;
#Column(name = "firstName")
#NotEmpty(message = "First name is required")
private String firstName;
#Column(name = "lastName")
#NotEmpty(message = "Last name is required")
private String lastName;
#Column(name = "email")
#NotEmpty(message = "Email is required")
#Email(message="Email Must be well formed")
private String email;
}
UserRepository :
public interface UserJpaRepository extends JpaRepository<User, Long> {
}
UserServiceImpl :
this.userJpaRepository.saveAll(users);
pom.xml
<?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.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.exostar</groupId>
<artifactId>FileUpload</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>FileUpload</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
</project>
Issue :
As per the User entity class , #Id is manually generated.
(I have a CSV file which has Id field which is read in User entity)
So Id is not auto generated
Whenever I call this.userJpaRepository.saveAll(users) and even when there is an User entity with Id already existing , the User entity gets overwritten.
That is , Id with same entity gets overwritten with new data.
It has to throw - Unique index or primary key violation error
However, when I try to insert duplicate entry into H2 database MANUALLY , it throws exception - Unique index or primary key violation
I also tried adding unique=true to Id field in User Entity but its not working
Can anybody please help on resolving this issue please ?
Well as it turns out that the behavior that you are seeing is because of the call to em.merge(...) in the save() implementation. Here is what actually happens:
#Transactional
#Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null.");
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity); // Update if the entity is not new
}
}
This is a sample code from SimpleJpaRepository implementation. you can use your own query methods for updating the existing query something like this:
#Modifying
#Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);

Map domain class to DTO class using Mapstruct and lombok in SpringBoot application with RestController

The below is my main application class.
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan("com.example.demo")
public class Demo1Application {
public static void main(String[] args) {
SpringApplication.run(Demo1Application.class, args);
}
}
Controller Class.
#RestController
public class JobAppController {
#Autowired
JobApplicationRepository jobApplicationRepository;
//#Autowired
//private JobApplicationMapper mapper;
JobApplicationMapper mapper = Mappers.getMapper(JobApplicationMapper.class);
#GetMapping("/hello")
public String greeting()
{
return "hello Mr";
}
#PostMapping("/save")
public JobApplicationDto save(#RequestBody JobApplicationDto jobApplicationDto)
{
JobApplication jobApplication = mapper.toEntity(jobApplicationDto);
jobApplication = jobApplicationRepository.save(jobApplication);
return mapper.ToDTO(jobApplication);
}
}
Mapper Interface.
#Mapper
#Component
public interface JobApplicationMapper {
//JobApplicationMapper mapper = Mappers.getMapper(JobApplicationMapper.class);
//({ #Mapping(target="employeeId", source="entity.id"),#Mapping(target="employeeName", source="entity.name")})
JobApplicationDto ToDTO(JobApplication jobApplication);
JobApplication toEntity(JobApplicationDto jobApplicationDto);
}
my pom file.
<?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.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.jobSearch</groupId>
<artifactId>demo-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo-1</name>
<description>Demo project for Spring Boot/JobSearch</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.0.Final</version>
</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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
<type>jar</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.0.Beta2</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
domain class.
#Entity
#Table(name = "Job_Application")
//#Data
//#AllArgsConstructor
//#NoArgsConstructor
public class JobApplication {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Id()
private Integer id;
#Column(name = "requisition_id")
private String requisition_id;
#Column(name = "job_posting_source")
private String job_posting_source;
#Column(name = "applied_date")
private Date applied_date;
#Column(name = "company")
private String company;
#Column(name = "current_status")
private String current_status;
#Column(name = "position")
private String position;
#Column(name = "location")
private String location;
//getters and setters follows...
dto class.
/*#Data
#AllArgsConstructor
#NoArgsConstructor
#Builder*/
public class JobApplicationDto {
private Integer id;
private String requisition_id;
private String job_posting_source;
private Date applied_date;
private String company;
private String current_status;
private String position;
private String location;
//getters and setters follows
when try to post data/dto (as JSON) into my db table through postman, the data gets inserted as null values
{
"requisition_id" : "1234",
"job_posting_source" : "indeed",
"applied_date" : "2020-08-15",
"company" : "softInc",
"current_status" : "under review",
"position" : "SE3",
"location" : "Himalayas"
}
the response after insertion is like so
{
"id": null,
"requisition_id": null,
"job_posting_source": null,
"applied_date": null,
"company": null,
"current_status": null,
"position": null,
"location": null
}
There is no error message. not sure what I am missing.
After thorough debug, I realized that there is no issue with the mapper implementation. however since I am using "lombok" for the domain and the dto classes, the getters and setters weren't being generated. So I manually added them now in the code and works as expected now.
PS: I would rate my self as a beginner with this, so any kind of discussion/suggestions are welcome.
I would edit the question now, as the issue is with lombok as to why the getters/setters aren't being generated.
I guess Lombok is missing as annotation processor..
Try:
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
</annotationProcessorPaths>
Checkout this for a working example.
Please note: there are several issues with Lombok / MapStruct. Both are annotation processors. Lombok generates getters / setters, MapStruct uses them. Timing is essential. Hence, MapStruct introduced an SPI to signify when generation is ready.

Error creating bean with name 'entityManagerFactory' not fixed by javaxb or hibernate dependencies

I realize this has been asked time and time again here but after trying the fixes from multiple responses I am still running into this problem.
I'm receiving an error when I try to run my spring API stating:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1080) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at com.max.rocketLeagueAPI.Main.main(Main.java:11) ~[classes/:na]
Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at org.hibernate.boot.spi.XmlMappingBinderAccess.<init>(XmlMappingBinderAccess.java:43) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.boot.MetadataSources.<init>(MetadataSources.java:87) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:179) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:149) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:54) ~[spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:360) ~[spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:382) ~[spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:371) ~[spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:336) ~[spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
... 16 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583) ~[na:na]
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
... 27 common frames omitted
Process finished with exit code 1
Here is my pom file. I have tried adding jaxb-api, hibernate-entitymanager, hibernate-core, and combinations of the three without any luck.
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.max</groupId>
<artifactId>rocketLeagueAPI</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>javax.xml.bind</groupId>-->
<!-- <artifactId>jaxb-api</artifactId>-->
<!-- <version>2.3.1</version>-->
<!-- </dependency>-->
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
This is my model class:
package com.max.rocketLeagueAPI.Models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.sql.Timestamp;
#Entity
#Table(name = "cars")
public class Car {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "car_id")
private int id;
private String name;
private String rarity;
private String platform;
#Column(name = "img_url")
private String imgUrl;
private boolean free;
#Column(name = "updated_at")
private Timestamp updatedAt;
public Car() {}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
public String getRarity() {
return this.rarity;
}
public String getPlatform() {
return this.platform;
}
public String getImgUrl() {
return this.imgUrl;
}
public boolean isFree() {
return this.free;
}
public Timestamp getUpdatedAt() {
return this.updatedAt;
}
}
Here is the table I am connecting to (or trying to)
mysql> describe cars;
+------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-----------------------------+
| car_id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(30) | NO | | NULL | |
| rarity | varchar(15) | YES | | NULL | |
| platform | varchar(15) | YES | | NULL | |
| img_url | varchar(255) | YES | | NULL | |
| free | tinyint(1) | YES | | 1 | |
| updated_at | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+--------------+------+-----+-------------------+-----------------------------+
7 rows in set (0.00 sec)
And my interface:
package com.max.rocketLeagueAPI.Repositories;
import com.max.rocketLeagueAPI.Models.Car;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface CarRepository extends JpaRepository<Car, Integer> {
// car filters
List<Car> findByPlatform(String platform);
List<Car> findByRarity(String rarity);
List<Car> findByFree(boolean isFree);
List<Car> findByRarityAndFree(String rarity, boolean isFree);
}
and my application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/rocketLeagueAPI
spring.datasource.username=max
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
I'm following a guide on writing a spring api but even when I use the exact code from the guide I get the same error. Is anything missing from what I have or annotated incorrectly?
After much more research I found the issue and fix. javaxb is no longer supported in the jdk11 so these dependencies need to be added:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
application.properties also required:
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=create
Hope this helps anyone else on running into this issue!

#query annotation doesn't work with hibernate-ogm and mongodb in spring boot

I wrote a Spring boot,hibernate orm application using mysql database.... But now I want to switch to mongodb... I used Hibernate-ogm for fulfill my requirement. When run the application the console shows successfully switch to mongodb using hibernate-ogm... But the query is not working... I import below packages for my repository to hibernate-orm and these imports works fine with mysql... But in hibernate-ogm #query annotation doesn't work...
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.jpa.repository.Query;
This is my model
#Entity
#Indexed
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String nic;
private String emp;
private String firstName;
private String lastName;
#NotEmpty
private String mobile;
private String email;
private String status;
private String agency;
#NotEmpty
#Column(unique = true)
private String userName;
#NotEmpty
private String password;
private String userIDandTime;
private String recentUpdateBy;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "user_roles",
joinColumns = {
#JoinColumn(name = "id")},
inverseJoinColumns = {
#JoinColumn(name = "roleId")})
private Set<Role> userRoles;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "user_units",
joinColumns = {
#JoinColumn(name = "id")},
inverseJoinColumns = {
#JoinColumn(name = "unitId")})
private Set<Unit> userUnits;
}
This is my full repository
package lk.tradeportal.repository;
import lk.tradeportal.domain.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
import org.springframework.data.jpa.repository.Query;
/**
* Created by Ignotus on 1/28/2017.
*/
public interface UserRepository extends CrudRepository<User, Long> {
#Override
User save(User user);
#Override
User findOne(Long id);
#Query("select u from User u where u.userName!='super#allSLSI'")
List<User> findAll();
#Query("select u from User u where u.agency = :agency and u.firstName !='admin'")
List<User> findAllStaffUsersByOGA(#Param("agency") String agency);
#Query("select u from User u where u.nic='N/A' and u.firstName='N/A' and u.email='N/A'")
List<User> profileNotCompletedUsers();
#Query("select u from User u where u.agency!='SLSI'")
List<User> chafindAll();
#Query("select u from User u where u.userName = :userName")
User getUserByLoginUserName(#Param("userName") String userName);
#Query("select u from User u where u.id = :userId")
User getUserByUserId(#Param("userId") Long userId);
#Query("select u.email from User u where u.agency !='SLSI'")
List<User> getEmails();
#Query("select a from User a where a.nic = :nic")
User getAgentByNIC(#Param("nic") String nic);
#Override
void delete(Long id);
#Override
void delete(User user);
}
This is my Service class
package lk.tradeportal.services;
import java.text.SimpleDateFormat;
import java.util.Date;
import lk.tradeportal.domain.Role;
import lk.tradeportal.domain.User;
import lk.tradeportal.repository.RoleRepository;
import lk.tradeportal.repository.UserRepository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import lk.tradeportal.domain.Unit;
import lk.tradeportal.repository.UnitRepository;
import lk.tradeportal.security.domain.AuthenticatedUser;
import org.springframework.security.core.context.SecurityContextHolder;
/**
* Created by ignotus on 1/31/2017.
*/
#Service
public class UserServices {
private static final Logger serviceLogger = LogManager.getLogger(UserServices.class);
#Autowired
private UserRepository userRepository;
#Autowired
private RoleRepository roleRepository;
#Autowired
private UnitRepository unitRepository;
#Autowired
private UserServices UserService;
public User getUserFromUserId(Long id) {
return userRepository.getUserByUserId(id);
}
public List<User> getAllUsers() {
Runtime.getRuntime().gc();
return userRepository.findAll();
}
public User getUserByLoginUserName(String userName) {
return userRepository.getUserByLoginUserName(userName);
}
public List<User> findAllStaffUsersByOGA(String agency) {
return userRepository.findAllStaffUsersByOGA(agency);
}
public List<User> profileNotCompletedUsers() {
return userRepository.profileNotCompletedUsers();
}
public List<User> getChaAllUsers() {
System.out.println(userRepository.chafindAll());
return userRepository.chafindAll();
}
public List<Role> getAllRoles() {
return roleRepository.findAll();
}
public List<Role> findTraderRoles() {
return roleRepository.findTraderRoles();
}
public List<Role> findMOIC() {
return roleRepository.findMOIC();
}
public List<Role> SuperADMINRoles() {
return roleRepository.SuperADMINRoles();
}
public List<Unit> getAllUnits() {
return unitRepository.findAll();
}
public void deleteUserById(String id) {
User user = userRepository.findOne(Long.valueOf(id));
userRepository.delete(user);
}
public User getAgentByNIC(String nic) {
return userRepository.getAgentByNIC(nic);
}
}
This is my application config.
package lk.tradeportal;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import javax.annotation.PreDestroy;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* Created by ignotus on 1/22/2017.
*/
#Configuration
#ComponentScan(basePackages = "lk.tradeportal")
#EnableWebMvc
#ImportResource(locations = "classpath:tradeportal-servlet-config.xml")
#EnableJpaRepositories(basePackages="lk.tradeportal.repository")
#EnableTransactionManagement
public class TRADEPORTALStarter extends SpringBootServletInitializer {
private static final Logger slsiLogger = LogManager.getLogger(TRADEPORTALStarter.class);
private static ConfigurableApplicationContext context;
public static void main(String[] args) {
slsiLogger.info("Starting application");
SpringApplication application = new SpringApplication(TRADEPORTALStarter.class);
context = application.run(args);
application.setRegisterShutdownHook(true);
}
#PreDestroy
private static void closeAppContext(){
context.close();
}
#Override
protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(TRADEPORTALStarter.class);
}
}
This is my persistence.xml
<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="ogm-jpa-tutorial" transaction-type="RESOURCE_LOCAL">
<!-- Use Hibernate OGM provider: configuration will be transparent -->
<provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
<class>lk.tradeportal</class>
<properties>
<property name="hibernate.ogm.datastore.provider" value="mongodb" />
<!--<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform" />-->
<property name="hibernate.ogm.datastore.create_database" value="true"/>
<property name="hibernate.ogm.datastore.database" value="trade_portal_db"/>
</properties>
</persistence-unit>
</persistence>
My dependencies are
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
</dependency>
<!--handle servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!--<Email Dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>1.4.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.1</version>
</dependency>
<!--jasper-->
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>3.7.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.5.5</version>
<type>jar</type>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web-services -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
<version>1.5.1.RELEASE</version>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.ws.security/wss4j -->
<dependency>
<groupId>org.apache.ws.security</groupId>
<artifactId>wss4j</artifactId>
<version>1.6.19</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-libs -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-libs</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-security</artifactId>
<version>2.2.0.RELEASE</version>
<type>jar</type>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-mongodb</artifactId>
<version>5.1.0.Final</version>
<exclusions>
<exclusion>
<groupId>org.hibernate.hql</groupId>
<artifactId>hibernate-hql-parser</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.4.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.ogm/hibernate-ogm-core -->
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-core</artifactId>
<version>5.1.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-search-orm -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>5.6.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-search-engine -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-engine</artifactId>
<version>5.6.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.1.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.hql</groupId>
<artifactId>hibernate-hql-parser</artifactId>
<version>1.4.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
</dependencies>
What is the error in #query annotation. How I get I data from my database.. Please help me.