Spring JPA Test - InvalidDataAccessResourceUsageException - spring

I have an entity
#Data
#Entity
#Table(name = "VGI_TRADESDBO.TRADELOG")
public class TradeLog {
#Id
#Column(name="TRADE_ID")
private Long tradeId;
…
And a Repository
public interface TradeLogRepository extends JpaRepository<TradeLog, Long>{
And a schema.sql file
CREATE SCHEMA "VGI_TRADESDBO"
CREATE TABLE "VGI_TRADESDBO"."TRADELOG"
( "TRADE_ID" NUMBER(38,0),
Finally I have a cucumber step def that injects that Repository and tries to save to it
#DataJpaTest
#Sql({"schema.sql"})
public class TradesToTsoStep{
#Inject TradeLogRepository tradeLogRepo;
and yet I get a Column "TRADELOG0_.TRADE_ID" not found;
org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement
Has anyone run into this? And why is it sticking the 0_ into the column name?

Related

Create SQL view with panache

I'm using
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-reactive-panache</artifactId>
</dependency>
and I would like to generate an SQL view in the same way we generate tables, specifically as follows:
#Entity
public class Invoice extends PanacheEntityBase {
...
}
I've tried that way but with no really success, I can't found anything on this in quarkus' documentation:
#Entity
#Subselect("SELECT i.id as invoiceId, i.appointmentIds FROM invoice i")
public class BilledAppointments extends PanacheEntityBase {
#Column
public Long invoiceId;
#Column
public String appointmentsIds;
}
I figured out that views are not managed by frameworks but only by databases. So it is not really possible to map a view to a "classic" entity, since Panache will interprate this as a table and create one. Moreover, if you create a view manually in your database that references one of your entities, it may be deleted if you adopt the drop-and-create strategy.
A solution is:
#Entity
public class MyTable extends PanacheEntityBase {}
#Entity
#Subselect("SELECT * FROM MyTable")
#Synchronize("MyTable")
public class MyView extends PanacheEntityBase {}
Helful answer
Hibernate documentation

Spring data jpa does not update existing row (Oracle) when using #sequencegenerator

New to spring data JPA. I have sequence created in oracle table. I am using JPARepository saveall() method to save the data. Inserts work without any problem but when i try to update any existing rows in the table it always tries to insert throwing unique constraint error since i have unique index created for that table.
Entity Class
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator1")
#SequenceGenerator(sequenceName = "emp_seq", name = "generator1",allocationSize = 1)
#Column(name = "USER_ID")
private Long id;
Save method invocation
public void persistEmployees(List<Employee> employees) {
employeeRepo.savaAll(employees);
}
Repository class
#Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> { }
How can i tell JPA to look for existing row before inserting? Any help is much appreciated!!!
In My Humble Opinion;
Using "Exists" condition-check as "sub-query" for all constrained columns, before Update will solve this.

Spring Boot repository save does not work (only shows a select)

I'm facing for hours with a strange proceeding in Spring Boot when try to save a mapped entity.
The entity class with a composite key that must all be set by the user is as follows:
package model
import javax.persistence.*
#Entity
#Table(name = 'MY_TABLE')
#IdClass(MyIdClass.class)
class MyClass implements Serializable{
#Id
#Column(name = "MY_COLUMN_1")
Long column1
#Id
#Column(name = "MY_COLUMN_2")
Long column2
#Id
#Column(name = "MY_COLUMN_3")
String column3
#Id
#Column(name = "MY_COLUMN_4")
Date date1
#Column(name = "MY_COLUMN_5")
Date date2
#Column(name = "MY_COLUMN_6")
BigDecimal column6
}
#Embeddable
class MyIdClass implements Serializable{
Long column1
Long column2
String column3
Date date1;
}
The corresponding repository is:
package repository
import org.springframework.data.repository.CrudRepository
interface MyRepository extends CrudRepository<MyClass, Long>{
}
My service is:
package service
import model.MyClass
import repository.MyRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
#Service
class MyService {
#Autowired
MyRepository repository
void save(MyClass myClass) {
repository.save(myClass)
}
}
My controller mounts a MyClass object with all data set, including the composite key. When it calls the service save method the object is not inserted in the database. I saw the logs and checked that there is a SELECT in MY_TABLE instead of INSERT. I tried not to inform the composite key in the object and then the save method did an INSERT with error due to null values in the primary key.
I really don't understand why the insertion is not done when the composite key has values. How can I solve it?
I've already tried with #Transactional in service class and didn't work. I didn't do any Transaction configuration in the project since Spring Boot delivers it as default.
Thanks.
It seems you are using MyIdClass as the Id for MyClass. So, the Repository should be:
interface MyRepository extends CrudRepository<MyClass, MyIdClass>{
}
Hope this help.
I take your code sample and tried it on a sample Spring Boot project, where I was able to save to H2 DB (In memory) with #Embeddable & #EmbeddedId annotations. If you would like to verify, you can clone the GitHub repo and run the BootJpaApplication.java as a Java Application.
After execution access the H2 console with the below link from local where table details can be verified.
http://localhost:8080/h2-console
https://github.com/sujittripathy/springboot-sample.git
Hope the detail helps:)

DBUnit NoSuchColumnException in parent class

So I'm getting this error:
org.dbunit.dataset.NoSuchColumnException: TOYOTA.CAR_MAKE - (Non-uppercase input column: CRTE_DT_TM) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive.
when trying to populate a H2 DB using DbUnit in the context of a Spring JUnit test. The DDL for the H2 DB is created from JPA-annotated classes. However, the column does exist, it is in an abstract class that is extended by the core class.
Let me explain. The core JPA class looks like this:
#Entity
#Table(name = "TOYOTA")
public class Toyota extends Car {
#Id
#Column(name = "TOYOTA_REF")
private String toyotaRef;
#Column(name = "TOYOTA_DEALER")
private String toyotaDealer;
// etc.
The parent class looks like this:
public abstract class Car {
#Column(name = "CAR_MAKE")
private String carMake;
#Column(name = "CAR_MODEL")
private String carModel;
I'm initiating tests like this:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = "classpath:/test-spring-config.xml") // Load Spring Test context
#TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class}) // Used to load test data onto DB})
#DatabaseSetup(value = {"classpath:/integrationTestData/Toyota.xml"})
#Test
#Transactional
public void testSomething() {
and my Toyota.xml data file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<TOYOTA TOYOTA_REF="TOY123"
TOYOTA_DEALER="Big Dealer"
CAR_MAKE="Toyota"
CAR_MODEL="Corolla"
/>
</dataset>
Any thoughts?
Fixed this myself. I had to add this JPA annotation to the parent class:
import javax.persistence.MappedSuperclass;
#MappedSuperclass
public abstract class Car {

Hibernate and JPA always load referenced tables

I am working with Hibernate 4+ Spring MVC + Spring Data with JPA annotations:
#Entity
public class ClassOne implements Serializable{
......
#OneToMany(mappedBy = "mapper", fetch=FetchType.LAZY)
private Set<ClassTwo> element = new HashSet<ClassTwo>(0);
//more fields
//getters and setters
//equals and hashcode
}
#Entity
public class ClassTwo implements Serializable{
......
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name = "CEN_CEN_CODIGO", nullable = false)
private ClassOne classOne;
//more fields
//getters and setters
//equals and hashcode
}
public interface ClassOneRepository extends CrudRepository<ClassOne, Long> {
#Override
#Query("select c from ClassOne c")
public List<ClassOne> findAll();
}
#Service
public class ClassOneService {
#Autowired
private ClassOneRepository classOneRepository;
#Transactional(readOnly=true)
public List<ClassOne> findAll() {
return classOneRepository.findAll();
}
}
And finally I call thie service from my #Controller
#Autowired
ClassOneService classOneService;
I expect results ONLY from ClassOne but retrieving the JOIN values with ClassTwo and all the database tree associate. Is it possible to get only values for ONE table using this schema? Is it a cache problem or Fetching not LAZY?
EDIT: I added the relatioship between two classes
Thank you
You must have the following anotation above your Set<ClassTwo> or its getter:
#OneToMany(fetch = FetchType.LAZY, ...)
See http://docs.oracle.com/javaee/7/api/javax/persistence/OneToMany.html#fetch()
It seems to be that simple "SELECT *" JPA query returns all eagerly fetched fields for the entity.
Please refer to: JPA - Force Lazy loading for only a given query
and http://forcedotcom.github.io/java-sdk/jpa-queries.
So my solution would be to use SessionFactory to get current session and then use "classic" method
return getCurrentSession().createCriteria(persistentClass).list();
Another possible way is to create let's say a POJO object without Set which uses the same table as ClassOne.
I've just added #Lazy for each #ManyToOne and #OneToMany relationship. It seems that Spring Data needs Spring annotations but I supposed that just was necessary to add fetch = FetchType.LAZY. No more Eager behaviours ;).
Thanks for your responses

Resources