How to get column name from JPA - spring-boot

My code:
empDet emp = repository.findByActiveFlag("Y");
Here empDet is a entity with 3 columns:
empid
empName
ActiveFlag
Table with 10 rows so i will use foreach
emp.forEach(e-> {
---mycode---
---and here i got values--
});
Now my question is how to get Column name from Jpa or foreach loop

If you have object of Entity class (empDet) in JPA then from that object you can get the all properties of that class.
As you know in JPA class represent table in database and properties represent columns of that table.
if you have an object of empDet e.i emp
empDet emp=repository.findByActiveFlag("Y");
Field[] members = emp.getClass().getDeclaredFields();
for(Field member:members){
System.out.println(member.getName());
}

Related

Implementing hierarchical DB tables with InheritanceType.JOINED and a `tenant_id` column in every table

I'm trying to implement a hierarchical structure using the InheritanceType.JOINED approach to store data in hierarchical DB tables. One caveat is that in our multi-tenant solution, a tenant_id column needs to be present on every table (for security and legal export reasons), even though this is redundant in some cases. This requirement is fixed.
Issue is that when inserting data, the query Hibernate generates does not fill in the tenant_id on the parent- and childtable, causing a constraint error.
The tables in the DB would look like this:
Code for the abstract vehicle entity:
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
abstract class Vehicle(
var tenantId: Int,
var title: String
)
Car entity:
#Entity
class Car(
override var tenantId: Int,
override var title: String,
) : Vehicle(tenantId, title) {
var numberOfDoors: Int
}
Plane entity:
#Entity
class Plane(
override var tenantId: Int,
override var title: String,
) : Vehicle(tenantId, title) {
var numberOfPropellers: Int
}
When inserting a new Car in the database, Hibernate generates 2 queries, where the tenant_id is only added to the abstract Vehicle table:
insert into vehicle (tenant_id, title) values (?, ?)
insert into car (id, number_of_doors) values (?, ?)
Is there a way to instruct Hibernate to fill in the column on both tables?
One hack I've found is to implement a "second" tenantId variable on the class and specify a column explicitly, as such:
#Column(name = "tenant_id")
private val _tenantId: Int = tenantId
But it's not very clean and a neater solution would be nice.
Specifically in my case where the tenant_id column is a database setting, defining a computed default value on the tenant_id db column also works as a workaround:
current_setting('app.current_tenant', true)::INT

Entity Graph for nested associations of tables in Spring JPA

There are 3 tables in my db:
SalesOrderMaster
SalesOrderDetail
CustomerMaster
I have repository class SalesOrderDetailRespository.java which has this method findAll()
#EntityGraph(attributePaths = {"SalesOrderMaster"}, type = EntityGraph.EntityGraphType.FETCH)
List<SalesOrderInfo> findAll(#Nullable Specification<SalesOrderInfo> spec);
This is till now fetching the SalesOrderMaster record and associated SalesOrderDetails records. Now my requirement is in SalesOrderInfo class , I have added a new property for showing the Customer Information like Name , country which are there in CustomerMaster table.
The customerMaster table is related to SalesOrderMaster by customerId column. How do I add CustomerMaster table in the existing EntityGraph so that I can get this info?

JPA nativeQuery with UNION does not support pagination

Consider the following tables:
TABLE A
id
sys_time
user_id
rent_time
TABLE B
id
sys_time
occur_time
I would like to use a UNION query in MYSQL to have this table and put data from both tables row by row with sys_time order:
TABLE AB
id
sys_time
user_id
occur_time
rent_time
I use the following query:
select id, sys_time, user_id, null as occur_time, rent_time from open_close
union
select id, sys_time, null as user_id, occur_time, null as rent_time from periodic
order by sys_time desc;
Now I define an #Entity with the following structure:
...
#Data
#Entity
#NamedNativeQuery(
name="TotalEntity.getTotal"
, query="select id, sys_time, user_id, null as occur_time, rent_time from open_close\r\n"
+ "union\r\n"
+ "select id, sys_time, null as user_id, occur_time, null as rent_time from periodic \r\n" + "order by sys_time desc;"
, resultClass=TotalEntity.class
)
...
// Entity Fields and so on
and the corresponding Repository:
#Repository
public interface TotalRepository extends JpaRepository<TotalEntity, BigInteger> {
#Query(nativeQuery = true)
public List<TotalEntity> getTotal();
}
Everything is OK up to now.
Now I want to add pagination:
#Repository
public interface TotalRepository extends JpaRepository<TotalEntity, BigInteger> {
#Query(nativeQuery = true)
public Page<TotalEntity> getTotal(Pageable page);
}
and use this:
...
private TotalRepository tr;
...
Pageable pageable = PageRequest.of(page, size,
direction.toUpperCase().equals("ASC") ? Sort.by(sort).ascending() : Sort.by(sort).descending());
Optional<Page<TotalEntity>> pe = Optional.ofNullable(tr.getTotal(pageable));
The following exception is thrown:
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'limit 20' at line 4
It seems that Hibernate can not modify the nativeQuery to add pagination statements. And I know that JPQL and JPA does not supprt UNIONs. Is there any workaround for this?
A workaround would be to introduce a view in the database layer with the union clause, and then execute the query upon the view.
This way, you can hide the union from JPA layer and queries can be executed using pageable as usual.
CREATE VIEW view_name AS
select id, sys_time, user_id, null as occur_time, rent_time from open_close
union
select id, sys_time, null as user_id, occur_time, null as rent_time from periodic
And modify the JpaRepository to query upon the view using prefered way, like native queries, column projections etc.
If you are not planning to use other functionalities from Pageable interface like getting the total records count, number of current slice etc., then try using offset and limit keywords in the query directly for the pagination.
Note : offeset corresponds to page and limit corresponds to size of content in the page

How to replace SQL Query CONDITION in Spring JPA native query

I have a spring jpa native query(actual query has multiple tables connected) something like below.
#Query(nativeQuery = true, value="
select id, name from TABLE where id NOT IN ('2', '3')")
List<Object> getValueForNOTIN()
#Query(nativeQuery = true, value="
select id, name from TABLE where id IN ('4', '5')")
List<Object> getValueForIN()
Instead of 2 methods, I want to use one method which replaces NOT IN and IN with this 'replaceClause' value.
List<Object> getValueForBoth(#Param("replaceClause)" String replaceClause)
I get error on start of server. Can't I do like this?
You can use a static string like
private String SELECT_NOT_IN_QUERY = "select id, name from TABLE
where id NOT IN ('id1', 'id2')"
private String SELECT_IN_QUERY = "select id, name from TABLE
where id IN ('id1', 'id2')"
then look for id1 and id2 and replace with its values. use the right static string accordingly.

How to fetch jsonb column through jpa springboot?

I have one table which contains one column 'details' as jsonb data type. The content is
{
"name": "username",
"value": "user1",
"is_required": true
}
for one row.
I want to write one jpa hibernate query in spring boot to fetch this record when name == username for details column.
Something like this:
select details->>'value' from table where details->>'name' = 'username';
This syntax does not work in spring boot hibernate query.
I got the answer. Use
#Query(value="select details->>'value' from table where details->>'name' = 'username'", nativeQuery=true)

Resources