InvalidSyntaxException passing GraphQL query parameters - spring

Trying to implements the code to be able to execute the following graphql query:
query FIND_BY_BATCHID_LIMIT {
findByBatchIdAndLimit(batch_id: 10, limit: 5) {
id
first_name
last_name
}
}
So the following implementation:
query.graphqls
type Query {
findByBatchIdAndLimit(batch_id: Int!, limit: Int!): [RawEntity]
}
Repository and Query
#Repository
public interface RawRepository extends JpaRepository<RawEntity, Integer> {
#Query(value = "SELECT * FROM rawdata where batch_id = :batch_id LIMIT :limit", nativeQuery = true)
List<RawEntity> findByBatchIdAndLimit(Integer batch_id, Integer limit);
}
#Component
public class Query implements GraphQLQueryResolver {
#Autowired
private RawRepository repository;
public List<RawEntity> findByBatchIdAndLimit(Integer batch_id, Integer limit) {
return repository.findByBatchIdAndLimit(batch_id, limit);
}
}
But getting a:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [graphql.kickstart.tools.SchemaParser]: Factory method 'schemaParser' threw exception; nested exception is graphql.parser.InvalidSyntaxException: Invalid Syntax : offending token '!' at line 46 column 11
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
... 139 common frames omitted
Caused by: graphql.parser.InvalidSyntaxException: Invalid Syntax : offending token '!' at line 46 column 11
While the following finder implementation work:
query.graphqls
type Query {
findByLimit(limit: Int!): [RawEntity]
}
Repository and Query
#Repository
public interface RawRepository extends JpaRepository<RawEntity, Integer> {
#Query(value = "SELECT * FROM rawdata LIMIT :limit", nativeQuery = true)
List<RawEntity> findByLimit(Integer limit);
}
#Component
public class Query implements GraphQLQueryResolver {
#Autowired
private RawRepository repository;
public List<RawEntity> findByLimit(Integer limit) {
return repository.findByLimit(limit);
}
}
query FIND_BY_LIMIT {
findByLimit(limit: 5) {
id
first_name
last_name
}
}
So might be the way I'm passing the batch_id, limit params, but googling, sounds the way to pass params.
Any ideas ?

Solved. The issue came from the Voyager dependency:
pom.xml when the question was raised:
<!-- GraphQL -->
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>${graphql.version}</version>
</dependency>
<!-- Voyager-->
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>voyager-spring-boot-autoconfigure</artifactId>
<version>${voyager.version}</version>
<scope>runtime</scope>
</dependency>
Working pom:
<!-- GraphQL -->
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>${graphql.version}</version>
</dependency>

Related

Doing custom query by a one of multiple primary keys throw me errors

My custom #Query of a table with multilple “primary keys” doen'twork.
In (image1) i show the basic structure i used to build my backend.
I start declaring my entity “Absentismos” and a other file to declare their primary keys “AbsentismoPrimaryData” with #Embeddable annotation.
#Entity
#Table(name="absentismo_incidencias")
#Getter
#Setter
public class Absentismos {
#EmbeddedId
public AbsentismoPrimaryData absentismoPrimaryData;
#Column(name="FECHA_INICIO")
public String fechaInicio;
#Column(name="FECHA_FINAL")
public String fechaFinal;
#Column(name="CANTIDAD")
public Integer cantidad;
}
#Embeddable
#Getter
#Setter
public class AbsentismoPrimaryData implements Serializable {
#Column(name="COD_TRABAJADOR")
public String codTrabajador;
#Column(name="CONCEPTO")
public String concepto;
//#DateTimeFormat(pattern = "dd-MM-yyyy")
#Column(name="FECHA_REGISTRO", insertable = false, updatable = false)
public String fechaRegistro;
}
Second, defined my repository with JPA.
#Repository
public interface AbsentimosRepository extends JpaRepository<Absentismos, AbsentismoPrimaryData> {
#Query(value="SELECT u FROM Absentismos u WHERE to_char( u.fechafiltro ,'yyyymmdd') = ?1",nativeQuery = true)
List<Absentismos> findAbsentismosByFechaRegistro(String fechaRegistro);
List<Absentismos> findByCantidad(Integer fechaRegistro);
}
Third, built my services
#Service
public class AbsentismoService {
#Autowired
private AbsentimosRepository repository;
public List<Absentismos> getAbsentismos(String fechaRegistro){
return repository.findAbsentismosByFechaRegistro(fechaRegistro);
}
public List<Absentismos> getByCantidad(Integer codTrabjador){
return repository.findByCantidad(codTrabjador);
}
}
and the controller.
#RestController
#RequestMapping("/absentismo")
public class AbsentismoController {
#Autowired
private AbsentismoService service;
#GetMapping()
public ResponseEntity<List<Absentismos>> getAbsentismos(#RequestParam("fechaRegistro") String fechaRegistro){
return new ResponseEntity<List<Absentismos>>(service.getAbsentismos(fechaRegistro), HttpStatus.OK);
}
Finally, my object in JSON format have this shape:
{
"absentismoPrimaryData": {
"codTrabajador": "10000576",
"concepto": "1413",
"fechaRegistro": "2009-07-16 00:00:00"
},
"fechaInicio": "2009-07-16 00:00:00",
"fechaFinal": "2009-07-31 00:00:00",
"cantidad": 16
}
In a table with unique primary key #Id, it works good. But, In this case i need to do a query by date with the field “fechaRegistro”.
However, After i try calle findAbsentismosByFechaRegistro function, the console show me this error:
Hibernate: SELECT u FROM Absentismos u WHERE to_char( u.fechafiltro ,'yyyymmdd') = ?
2022-03-29 14:10:38.432 WARN 14308 --- [nio-8082-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 942, SQLState: 42000
2022-03-29 14:10:38.433 ERROR 14308 --- [nio-8082-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ORA-00942: la tabla o vista no existe
2022-03-29 14:10:38.450 ERROR 14308 --- [nio-8082-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
oracle.jdbc.OracleDatabaseException: ORA-00942: la tabla o vista no existe
image1

Compilation error using both HashKey and RangeKey in dynamoDB with Springboot

I am using dynamDb with my springboot application. I am trying to save data in the table which has hashKey and sortKey. Initially I tried to annotate my HaskKey and sortKey with #DynamoDBHashKey and #DynamoDBRangeKey respectively. However this was giving me compilation issues. Upon search I found this article https://github.com/derjust/spring-data-dynamodb/wiki/Use-Hash-Range-keys which explains how in springboot we need to create a composite key/id with annotation #id. This id will not be part of the table.
I implemented the same however I still get compilation error:
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'eventRepository' defined in com.accuity.kyc.hep.repository.EventRepository defined in #EnableDynamoDBRepositories declared on DynamoDBConfig: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/data/repository/core/support/ReflectionEntityInformation\r\n\tat org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)\r\n\tat org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)\r\n\tat org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)\r\n\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944)\r\n\tat org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)\r\n\tat org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)\r\n\tat org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)\r\n\tat org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)\r\n\tat org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)\r\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:302)\r\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)\r\n\tat org.springframework.boot.SpringApplication.run(SpringApplication.java:1290)\r\n\tat com.accuity.kyc.hep.HepApplication.main(HepApplication.java:16)\r\nCaused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'historyEventRepository' defined in com.accuity.kyc.hep.repository.HistoryEventRepository defined in #EnableDynamoDBRepositories declared on DynamoDBConfig: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/data/repository/core/support/ReflectionEntityInformation\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)\r\n\tat org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)\r\n\tat org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)\r\n\tat org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)\r\n\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380)\r\n\tat org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)\r\n\tat org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)\r\n\tat org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)\r\n\t... 19 common frames omitted\r\nCaused by: java.lang.NoClassDefFoundError: org/springframework/data/repository/core/support/ReflectionEntityInformation\r\n\tat java.base/java.lang.ClassLoader.defineClass1(Native Method)\r\n\tat java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)\r\n\tat java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)\r\n\tat java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)\r\n\tat java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)\r\n\tat java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)\r\n\tat java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)\r\n\tat java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)\r\n\tat java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)\r\n\tat org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityMetadataSupport.getEntityInformation(DynamoDBEntityMetadataSupport.java:125)\r\n\tat org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactory.getEntityInformation(DynamoDBRepositoryFactory.java:104)\r\n\tat org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactory.getDynamoDBRepository(DynamoDBRepositoryFactory.java:128)\r\n\tat org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactory.getTargetRepository(DynamoDBRepositoryFactory.java:150)\r\n\tat org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:324)\r\n\tat org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:322)\r\n\tat org.springframework.data.util.Lazy.getNullable(Lazy.java:230)\r\n\tat org.springframework.data.util.Lazy.get(Lazy.java:114)\r\n\tat org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:328)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)\r\n\t... 30 common frames omitted\r\nCaused by: java.lang.ClassNotFoundException: org.springframework.data.repository.core.support.ReflectionEntityInformation\r\n\tat java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)\r\n\tat java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)\r\n\tat java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)\r\n\t... 50 common frames omitted\r\n"}
My entity class looks like this:
#DynamoDBTable(tableName = "Event")
#NoArgsConstructor
public class Event {
#Id
private EventId eventId;
#DynamoDBHashKey(attributeName = "id")
#DynamoDBAutoGeneratedKey
public String getId() {
return eventId != null ? eventId.getId() : null;
}
public void setId(String id) {
if (eventId == null) {
eventId = new eventId();
}
eventId.setId(id);
}
#DynamoDBRangeKey(attributeName = "eventDate")
public Date getEventDate() {
return eventId != null ? eventId.getEventDate() : null;
}
public void setEventDate(Date eventDate) {
if (eventId == null) {
eventId = new eventId();
}
eventId.setEventDate(eventDate);
}
}
Composite key class:
#NoArgsConstructor
#AllArgsConstructor
public class EventId {
private String id;
private Date eventDate;
#DynamoDBHashKey(attributeName = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#DynamoDBRangeKey(attributeName = "eventDate")
public Date getEventDate() {
return eventDate;
}
public void setEventDate(Date eventDate) {
this.eventDate = eventDate;
}
}
Repository:
#EnableScan
#Repository
public interface EventRepository extends CrudRepository<Event, EventId> {
}
For dependency I am using:
id 'org.springframework.boot' version '2.6.1' and
com.github.derjust:spring-data-dynamodb:5.1.0
I have followed the similar example from couple of other sources. I can not see what am I missing.
Please help.
There is an open issue for this, https://github.com/derjust/spring-data-dynamodb/issues/279. It appears the library is not compatible with Spring Boot 2.2. Per one of the commenters there is a fork available that may support this, but I haven't found this yet.
EDIT: The repository where this supposedly works now is at https://github.com/boostchicken/spring-data-dynamodb.

Springboot cassandra frozen value not recognised

I have a springboot application which I hooked up with cassandra. I am trying to create a map inside a map but getting the below exception. Seems to me that even though I use #FrozenValue, it is still sending the cal without the keyword frozen
Error
Caused by: org.springframework.data.cassandra.CassandraInvalidQueryException: Query; CQL [CREATE TABLE IF NOT EXISTS assessmentsubmissionentity (studentid text, assessmentid text, values map<text, map<text, text>>, PRIMARY KEY ((studentid, assessmentid)));]; Non-frozen collections are not allowed inside collections: map<text, map<text, text>>; nested exception is com.datastax.driver.core.exceptions.InvalidQueryException: Non-frozen collections are not allowed inside collections: map<text, map<text, text>>
at org.springframework.data.cassandra.core.cql.CassandraExceptionTranslator.translate(CassandraExceptionTranslator.java:139) ~[spring-data-cassandra-2.1.2.RELEASE.jar:2.1.2.RELEASE]
at org.springframework.data.cassandra.core.cql.CassandraAccessor.translate(CassandraAccessor.java:334) ~[spring-data-cassandra-2.1.2.RELEASE.jar:2.1.2.RELEASE]
Caused by: com.datastax.driver.core.exceptions.InvalidQueryException: Non-frozen collections are not allowed inside collections: map<text, map<text, text>>
at com.datastax.driver.core.exceptions.InvalidQueryException.copy(InvalidQueryException.java:49) ~[cassandra-driver-core-3.6.0.jar:na]
Code
#Table
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class AssessmentSubmissionEntity implements Serializable {
#PrimaryKeyColumn(type = PrimaryKeyType.PARTITIONED)
private String studentId;
#PrimaryKeyColumn(type = PrimaryKeyType.PARTITIONED)
private String assessmentId;
#FrozenValue
#Column
private Map <String, Map<String, String>> values;
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AssessmentSubmissionEntity that = (AssessmentSubmissionEntity) o;
return Objects.equals(studentId, that.studentId) &&
Objects.equals(assessmentId, that.assessmentId) &&
Objects.equals(values, that.values);
}
#Override
public int hashCode() {
return Objects.hash(studentId, assessmentId, values);
}
}
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
<exclusions>
<exclusion>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-mapping</artifactId>
</dependency>
It's a problem with Spring Data for Cassandra - they don't have mapping for frozen collections. See DATACASS-465 in their JIRA - it was filed more than year ago, but there is no progress on it...
I think that only solution is to use Object Mapper from the DataStax's Java driver, or manage your tables via CQL.

How should I create H2 using SpringBoot?

I'm starting to play with Spring Boot and as part of that I want to create an in memory DB to work with and bootstrap with the application.
Given the config/code below I get no errors in the startup log and can access the application ok, so it does startup (I get template errors about objects not existing), but I don't get any data back from the DAO when calling findAll() (or if I try to call findById(int) ).
So while it seems things are ok (no error in log, log shows it finds the sql to create schema ad attempts to run the data.sql statements) when I try to access data via the DAO I get no Exception, but no data returned.
Any ideas or observations on the code that might be a problem?
I've added the Spring Data / H2 stuff to my pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
Spring DAO:
public interface PersonDao extends CrudRepository<Person, Integer> {
}
DB props in application.properties:
server.contextPath=/
server.port=8080
spring.mvc.view.suffix=.ftl
datasource.mine.jdbcUrl=jdbc:h2:tcp://localhost/mem:clubmanagement
datasource.mine.user=sa
datasource.mine.password=
datasource.mine.poolSize=30
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=DEBUG
spring.jpa.hibernate.ddl-auto=create
My service:
#Service
public class MemberServiceImpl implements MemberService {
#Autowired
PersonDao dao;
#Override
public Optional<ClubMember> getClubMember(int id) {
Person dbPerson = dao.findOne(id);
if(dbPerson == null) {
return Optional.empty();
}
return Optional.of(fromEntity(dbPerson));
}
#Override
public List<ClubMember> allMembers() {
Iterable<Person> people = dao.findAll();
List<ClubMember> members = new ArrayList<>();
people.forEach(person -> {
members.add(fromEntity(person));
});
return members;
}
private ClubMember fromEntity(Person p) {
ClubMember member = new ClubMember();
member.setCurrentGrade(p.getCurrentGrade());
member.setFirstName(p.getFirstName());
member.setLastName(p.getLastName());
member.setAssociationMemberId(p.getAssociationMemberId());
member.setLastGradingDate(p.getLastGradingDate());
return member;
}
}
Schema.sql in resources/ :
create table CLUB
(id int not null, name varchar(60), association_member_id int);
create table PERSON
(
id int not null, grade_id int, first_name varchar(35), last_name varchar(35),
association_membership varchar(12), last_grading_date date
);
create table GRADE
(id int not null, name varchar(20));
In data.sql (again in resources directory):
insert into club (id, name, association_member_id) values (1, 'some club', '123');
insert into person (id, grade_id, first_name, last_name, association_membership, last_grading_date)
values (1, 1, 'name', 'lastname', 'a1234', '2016-03-23');
Entity class I am trying to retrieve (Trying to use Lombock, also new to me, to generate getters/setters):
#Entity
#Table(name = "person")
public #Data class Person {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private int id;
#JoinColumn(name = "grade_id")
private GRADE currentGrade;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "association_membership")
private String associationMemberId;
#Column(name = "last_grading_date")
#Temporal(value = TemporalType.DATE)
private Date lastGradingDate;
}
you want to add H2 database, but you added HSQLDB, please replace
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
with
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
EDIT
I noticed you have multiple issues in your code:
default schema file name is schema.sql not Schema.sql
names of tables in schema.sql are different than names in data.sql (PERSON vs person)
you used this spring.jpa.hibernate.ddl-auto=create in application.properties (default option), in this case JPA databases schema only will be automatically created (without data creation), so data.sql will not be executed, to fix this issues you can use validate or update option
I will write one simple example how to use H2 database with spring boot and JPA
This is the project structure:
Grade Entity
package com.shijazi;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="GRADE")
public class Grade {
#Id
#GeneratedValue
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Grade(int id, String name) {
super();
this.id = id;
this.name = name;
}
public Grade() {
}
}
GradeRepository.java
package com.shijazi;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface GradeRepository extends JpaRepository<Grade, Integer> {
}
Application.java
#SpringBootApplication
#RestController
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Autowired
private GradeRepository gradeRepo;
#RequestMapping(value="api/test")
public List<Grade> getall()
{
return gradeRepo.findAll();
}
}
application.properties
spring.jpa.hibernate.ddl-auto=validate
schema.sql
create table GRADE (id int not null, name varchar(20));
data.sql
insert into GRADE (id, name) values (2, 'name');
Dependencies in pom.xml
<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>
Now just run application and call this URL: http://localhost:8080/api/test
try to change the spring.jpa.hibernate.ddl-auto and see results
if you activate ddl-auto and have a schema.sql, BOTH of them are executed. But normally schema.sql is executed first. So the ddl-auto throws everything away, which was created by schema.sql and data.sql
After spending some time working through some ideas with #Safwan Hijazi in chat, came to the conclusion that what is happening is that the schema.sql and data.sql were being run but then the schema was recreated depending on the value (or lack of) of the spring.jpa.hibernate.ddl-auto property.
If not specified, spring/hibernate between them ended up recreating an empty schema (default seems to be create-drop for in memory DB).
If set the 'none' then that wouldn't happen and DB as created by the schema and data sql scripts would remain and the application functioned correctly.
See also: CrudRepository not reading data from schema.sql
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Just gives you an spring boot opinionated inclusion to the spring-boot-starter-data-jpa maven file, for the bill of material of all the dependencies. To use any one of the dependency defined in the Dependency management of the spring-boot-starter-data-jpa pom you will have to explicitly declare the dependency in dependency section of your pom file.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
To get the h2 database up and running with your application, you can specifiy the properties in your application.properties file at src/main/resources/application.properties use:
spring.h2.console.enabled=true
spring.h2.console.path=/h2DB
so when you run your application with spring application starter, you will be able to access the application at http://localhost:8080/h2DB login to the DB and you can verify if the database had the inserts in it or not?
Don't find the data in there then you know where to make a change to keep the data there.

JPA Stored procedure NoSuchMethodError

I'm following this JPA 2.1 StoredProcedureQuery as an example for what I'm working on.
Anyway, I have a Stored Procedure in the database named "XYZ" and I created a class:
#NameStoredProcedureQuery(
name = "createXYZ",
procedureName = "ZYX",
resultClasses = XYZObj.class,
parameters={
#StoredProcedureParameter(mode=ParameterMode.IN, name = "name", type = String.class),
#StoredProcedureParameter(mode=ParameterMode.OUT, name = "id", type = String.class)})
public class XYZObj {
private String id;
private String name;
...
}
Here is my DAO class:
#Stateless
public class XYZDAO{
#PersistenceContext(unitName = "PU")
private EntityManager em;
public String createXYZ(String name){
StoredProcedureQuery query = em.createNamedStoredProcedureQuery("createXYZ");
query.setParameter("name", name);
query.execute();
return query.getOutputParameterValue("id")
}
...
}
RESTFUL:
#Stateless
#Path("/XYZ")
public class XYZServlet{
#EJB
private XYZDAO xyzDao;
#GET
#Path("test")
public Response test(){
xyzDao.createXYZ("myname");
return Response.satus(Status.NO_CONTENT).build();
}
}
pom.xml
...
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.6.0-M3</version>
</dependency>
...
I'm getting NoSuchMethodError at this line.
StoredProcedureQuery query = em.createNamedStoredProcedureQuery("createXYZ");
Does anyone knows why? Am I using the right version of JPA? Did I miss something?
Here is the actual error that i'm getting.
java.lang.ClassCastException: java.lang.NoSuchMethodError cannot be cast to java.lang.exception
at javax.ejb.EJBException.getCauseByException(EJBException.java:23)
at com.sun.jersey.server.impl.ejb.EJBExceptionMapper.toResponse(EJBExceptionMapper.java:63)
at com.sun.jersey.server.impl.ejb.EJBExceptionMapper.toResponse(EJBExceptionMapper.java:54)
at com.sun.jersey.server.impl.ejb.EJBExceptionMapper.toResponse(EJBExceptionMapper.java:67)
at com.sun.jersey.server.impl.ejb.EJBExceptionMapper.toResponse(EJBExceptionMapper.java:54)
truncated. see log file for complete stacktrace
Thanks
Your project compilation looks like it's correctly referencing JPA 2.1, but a NoSuchMethodError indicates that the EntityManager available at runtime is from an earlier JPA version. The EntityManager is probably provided by your EJB container. Consult the documentation of whatever application server you are using to determine how to upgrade to JPA 2.1.
EDIT:
You should also mark whatever maven dependencies that are provided by your application server as <scope>provided</scope> in your pom.xml.

Resources