JPA Entity mapping SQL Function result to transient field - hibernate

Instead of calling SQL function "manually" for every entity, is there any way to map its result to an entity transient field's ?
#XXXX(call function with param ?)
private int calculatedValue;
Thanks

You should be able to use Hibernate's #Formula annotation:
https://docs.jboss.org/hibernate/orm/5.1/javadocs/org/hibernate/annotations/Formula.html
https://thoughts-on-java.org/hibernate-tips-calculate-entity-attributes-formula/

Related

How to query more than one columns but not all columns with #Query but still use the Domain Data Model to map with Spring Data JDBC?

My Data model is
#Getter
#Setter
public class Customer {
#Id private ID id;
#CreatedDate protected Instant createdAt;
#LastModifiedDate protected Instant updatedAt;
#CreatedBy protected String createdBy;
#LastModifiedBy protected String updatedBy;
#Version protected Long version;
private UUID orderId;
private String offer;
}
My Repository is
public interface CustomerRepository extends CrudRepository<Customer, UUID> {
#Query(
"SELECT ID, Offer FROM Customer WHERE orderId = :orderId ")
List<Customer> findCustomerByOrderId(
#Param("orderId") UUID orderId);
}
This will result in an exception saying 'orderId column not found [42122-190]'. So Spring expects you to always query all the columns. I understand that with JPA we have a strong mapping between the Entities and the Data Schema. But the whole point of spring data JDBC is avoiding the tight coupling between POJO's data model and database schema. Why not the EntityRowMapper is just mapping NULL to the properties which are not part of the query?
Is there a way to tell the RowMapper used, to ignore properties which are not part of the query? Creating separate RowMapper for these simple queries seems a lot of unnecessary work.
I still can work around this by changing the query like
#Query(
"SELECT ID, Offer, OrderId, null as CreatedAt, null as CreatedBy, null as UpdatedAt, null as UpdatedBy, null as Version FROM Customer WHERE orderId = :orderId ")
But this will still serialize the entire object with null values. Am I missing something obvious here?
Note This is not Spring Data JPA. Its Spring Data JDBC.
Edit
Looking more into it, the exception is from h2 database lib.
Caused by: org.h2.jdbc.JdbcSQLException: Column "orderid" not found [42122-190]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3129)
at org.h2.jdbc.JdbcResultSet.get(JdbcResultSet.java:3217)
at org.h2.jdbc.JdbcResultSet.getObject(JdbcResultSet.java:522)
at com.zaxxer.hikari.pool.HikariProxyResultSet.getObject(HikariProxyResultSet.java)
at org.springframework.data.jdbc.core.EntityRowMapper.readFrom(EntityRowMapper.java:127)
You can't at least right now.
There are three solutions to this, two of which you already pointed out:
extend your select statement with , NULL as <column-name> for all the missing columns.
I'm not sure if
But this will still serialize the entire object with null values.
means that this isn't working for you in some way.
specify a RowMapper.
You could use a class containing exactly the fields returned by the query. It could even have getters for the other columns if you want an interface implemented by both your normal entity and the partial entity.
You write:
But the whole point of spring data JDBC is to avoid the tight coupling between pojo's data model and database schema.
This is not quite right.
An important goal of Spring Data JDBC is to not have a run time connection between entities and table rows.
This would require proxies or similar and brings a lot of complexity.
But the structural mapping between entities and table is probably going to be stronger (and certainly is right now) since all the variants of mappings available in JPA bring complexity.
And the main goal in Spring Data JDBC is to be conceptually simpler than JPA.
You also ask
Why not the EntityRowMapper is just mapping NULL to the properties which are not part of the query?
I'm not sure if I actively thought about it when I coded it but I don't like the idea of defaulting to NULL because this would make it easy to accidentally not load a column because you have a typo in an alias.
But I'm not against alternative solutions.
If you have an idea please create a feature request.

Column not mapped hibernate

I use JPA annotations for mapping. In my table to map, i use #Entity annotation, and in this table, i have a column that I do not want to map.
Is there an annotation to declare that a column is not mapped?
You can use #Transient:
#Transient
private String abc;
for more informations Annotation Type Transient

Mapping PostgreSQL XML type to byte[] field of entity bean

We need to map an xml field in postgres table to Java entity field of type byte[].
We are using Hibernate for ORM.
Please let us know best method to do this.
Thanks!
This is done by implementing org.hibernate.usertype.UserType interface.
Then annotated the entity as given below:
#Column(columnDefinition="xml")
#Type(type="app.domain.XmlType")
private String contentXml;

How do I “filter” queries (where clause) on an entity by default?

I have a hibernate entity in my play! project that is backed by a mysql database and queries using JPA.
What I now want to do is to add an "archive" facility to my app which deletes this entity as far as the user is concerned.
However there are still other entities which will reference it so I cannot do a delete on the entity , plus I want the ability to restore it from the archive.
However I do not want it to appear in lists or searches by default but of course still need the ability to access the data there on some occasions such as when the user is examining an item that references it.
There are a number of queries that reference the entity and I could add a WHERE clause to each of these but I am also using some of the built in query methods such as findAll().
I think it would be a lot cleaner if I could somehow add the where clause by default.
Is there any way to do this?
You can use the Hibernate #FilterDef and #Filter Annotations on your Entity.
See the documentation.
http://docs.jboss.org/hibernate/orm/4.0/manual/en-US/html/filters.html
You probably also want to create a interceptor/hook for the JPA Plugin that automatically enables your filter when a hibernate session is started... but for the beginning, a #Before Filter in your controller should do the trick.
You have two solutions here:
If you are using Hibernate You can use #Where(clause = "column to filer") on the entity bean.
#Entity
#Where(clause = "isActive='false'")
public class Product {
//...
#Column
private Boolean isActive;
}
Or If using EclipseLink JPA implementation then Use #AdditionalCriteria("column to filer") to define parameterized views on data.
#Entity
#AdditionalCriteria("isActive='false'")
public class Product {
//...
#Column
private Boolean isActive;
}
For more info:
#AdditionalCriteria
#Where

JPA query for DTYPE

I have a single table which is generated from two jpa entities (inheritance). So we have a DTYPE column generated in the database table which has entity name has values.
How do I write a jpa query to fetch data for any given entity. i.e DTYPE = 'A'?
I just tried using DTYPE in jpa query but as expected I got an error "Could not resolve property". Please let me know how to write this query.
Note - I dont want to use native query.
Update:
I have class A and subclass AA which extends A. DTYPE has two values A and AA.
When I query for A, I get all the A plus AA entities. How to exclude AA when I query for A?
Simply add a simple field dtype in your parent class.
#Column(insertable = false, updatable = false)
private String dtype;
And so, you can use it in your JPQL query
Assuming you have three entities:
Party (superclass)
Person (extends Party)
Organization (extends Party)
where the last two are the two entities you store with a discriminator column, your JPA-QL query should be as simple as:
select p from Person p
to get all people. JPA is smart enough to figure it out. Likewise you can do:
select p from Party p
and get all of them.
You can use the entity names in your JPA queries, the discriminator column is abstracted away.
Suppose you have two entity classes SubClassA and SubClassB, which both inherit from SuperClass, then you can query for these entites like so:
FROM SubClassA WHERE [...]
or
FROM SubClassB WHERE [...]
If you want to query for both entities, use
FROM SuperClass WHERE [...]
In addition of what #SCH post, and as that didn't directly work for me, using Oracle, I was getting an Exception saying that "dtype" was kind of a reserved keyword. I then did
#DiscriminatorColumn(name = "myDType")
class abstract AbstractClass{
#Column(insertable = false, updatable = false)
private String myDType;
[...]
That worked fine for me, as this way I could dynamically change the Type I want to query using a where condition instead of changing the FROM statement.

Resources