JPA #Formula without Schema Name or Configure with entity class - java

I have two tables, A_TABLE and B_TABLE. in A_TABLE entity class need on formula which has B_TABLE column combination like below code,
Working Code:
A_TABLEEntity {
#Column("BM_NAME_I")
private String bmdName;
#Formula("(select b.LAST_NAME || ', '||b.FIRST_NAME||' ('||b.BM_NAME||')'
from BR_SCHEMA.B_TABLE b where UPPER(b.BM_NAME)=UPPER(BM_NAME_I))")
private string nameCombinationB;
}
Need solution in Formula :
1) Is it possible to provide any way to give B_TABLEEntity class instead of B_TABLE directly and columns from B_table entity class?
And I have tried with entity class its throwing error, - table or view does not exist
2) Is it possible to avoid to give SCHEMA name in B_TABLE before in formula?
And without schema error is throwing - table or view does not exist
Please help me above #Formula JPA code

You should definitely look here:
https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#mapping-column-formula
According to the described comment, #Formula takes only native sql and the article warns you about coupling to the specific database in some cases.
You should be aware that the #Formula annotation takes a native SQL
clause which may affect database portability.
As the #Formula requires native SQL, you should always include schema. I think that some DB's have default schema that does not need to be defined explicitly.
For some advanced operations, I would probably provide some annotation like #PostLoad and load desired properties using good old entitymanager or direct jdbc.
Maybe these links may help:
https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#basic
https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#fetching

Related

How does Spring JPA derive queries?

I am wondering how does Spring JPA derive queries from methods. As an example, if I was to type
interface CarRepo extends CrudRepository<Car, Long>{ findByCarMake(Make make) }
my query would be automatically derived from the method and would be something as "SELECT * from Car WHERE carMake = xxxxx"
I do understand this concepts but I would like to understand how it works behind the scenes. So, how does it actually derive a query from the method name?
I am aiming at creating a similar thing to suit our needs for a NestJs project so in Typescript not Java and also for an..."unorthodox" database which does not have such support out of the box( Neo4J).
I ll be very grateful to whom can and will help me.
Spring Data JPA derives the queries from the method names in your repository.
There are certain keywords that are reserved by Spring. One the one hand, there are query subject keywords like findBy, existsBy, countBy, etc. which influence the return type of the method. On the other hand, there are operators like and, or, isIn, between, etc. that are applied to the actual query logic.
You start your query with a query subject keyword like findBy and then the fields of your entity (and optionally operators and more fields). You can even have nested fields like findByProviderName where your entity has a field provider which has a field name. If you define an invalid property or property path (e.g. findByProviderNamw), your Spring Boot application would fail on startup. You can find more about defining query methods in the official spring reference.
Spring Data using part tree JPA queries, than map them into SQL query by pre-defined parts.

Using JOOQ just to store table/column names and types with no regard to Record types

I'm currently evaluating JOOQ because I believe I started reinventing the wheel which looks very close to part of JOOQ :)
Now, while digging in great JOOQ documentation I've found that my use case lies somewhere between Using JOOQ as SQL Builder and Using JOOQ as SQL Builder with Code generation i.e. I would like to:
Create plain SQL strings like it is shown in Using JOOQ as SQL Builder part
Instead of using hard-coded DSL.fieldByName("BOOK","TITLE") constructs, I prefer storing name of a table along with it's column names and types like it's shown in Using JOOQ as SQL Builder with Code generation part
I prefer not to use code generation (at least not on regular basis), but rather creating TableImpl myself when new table is needed.
While digging in manual, I've found how table implementation should look like in chapter Generated tables. However, TableImpl class as well as Table interface should be parameterized with record type and the same goes for TableField class. I believe this is done for easier type inference when directly querying database and retrieving results, though I may be mistaken.
So my questions are:
Is there a guide in manual on how to create Table and TableField implementations? Or I can simply generate them once for my database schema and use generated code as a guideline?
How can I gracefully "discard" record type parameters in implemented classes? First, I thought about using java.lang.Void class as type parameter but then I noticed that only subclasses of Record are allowed... The reason is that I don't need record types at all because I plan to use generated by JOOQ SQL queries in something like Spring JdbcTemplate so mapping is done by myself.
Thanks in advance for any help!
Given your use-case, I'm not sure why you'd like to roll your own Table and TableField implementations rather than using the ones generated by jOOQ. As you stated yourself, you don't have to regenerate that code every time the DB schema changes. Many users will just generate the schema once in a while and then put the generated artefacts under version control. This will help you keep track of newly added changes.
To answer your questions:
Yes, there are some examples around the use of CustomTable. You may also find some people sharing similar experiences on the user group
Yes you can just use Record. Your minimal custom table type would then be:
class X extends TableImpl<Record> {
public X() {
super("x");
}
}
Note that you will be using jOOQ's internal API (TableImpl), which is not officially supported. While I'm positive that it'll work, it might break in the future, e.g. as the super constructor signature might change.

Is there a way for selecting extra fields - not to be saved - in hibernate?

I want to execute the following sql in hibernate:
SELECT emp.*, utilsPkg.getEmployeeDisplayName(emp.id) FROM employee emp;
So far so good...
The thing is - I need it to be fetched to an entity - so I can update the employee.
Of course that the pl\sql function is not updateable nor part of the actual table...
How can I generate such an entity in hibernate - with a field that is calculated and not updateable?
Many thanks!
Using the #Formula annotation, as explained in the Hibernate documentation:
Sometimes, you want the Database to do some computation for you rather
than in the JVM, you might also create some kind of virtual column.
You can use a SQL fragment (aka formula) instead of mapping a property
into a column. This kind of property is read only (its value is
calculated by your formula fragment).
Use the #Transient annotation on the getter method for that property.
I'm not sure if I fully understand your question, but you can always use Hibernate entity lifecycle callbacks or you can provide it directly in your query:
select new MyEntity(o.column1, o.column2, utilsPkg.getEmployeeDisplayName(o.id)) from MyEntity as o where o.id = 5
Of course you must implement appropriate constructor.

How to select property from an entity in a hibernate relation

I have an entity class set up in Java, with a many-to-many relationship to another class. However, rather than selecting the entire entity collection, I'd like to select only a property from the child entities. The reason for doing this is that it will lower the amount of data being loaded into the system as I don't always need the entire entity depending on my view.
This is what I have so far:
#Entity
public class Disposition {
...
#ManyToMany
private List<Project> projects;
...
}
This works fine and retrieves a list of Project instances. However, I don't want to get all the Projects for the Disposition; I only want to retrieve Project.name.
The only solution I've been able to come up with so far is using the #Formula annotation but I'd like to avoid this if possible since it requires writing native SQL instead of HQL.
This view is read-only so I don't expect any changes to the data to be persisted.
you can use hql to only get the child's name. It would look something like
"select p.name from Project p where p.parent_id = ?"
you would have to tailor the variable names in that, and use a parameterized query to replace the ? with the id of the parent.
It is common to have tailored DAO methods for exactly this sort of situation.
This is where object relational mapping cannot help you anymore. But you can use the Query API which allows to query arbitrary objects by HQL, not SQL. Isn't #Formula using HQL, too?
It is not Hibernate, but the ebean project could interrest you. Ebean is an ORM project using the JPA annotations and allowing the lazy (partial) loading of objects.
In your example, getting only project names would result in this code:
List<Project> projects = Ebean.find(Project.class)
.select("name") // Only name properties are loaded
.where().eq("disposition", yourDisposition)
.findList();
Then, if you try to get project owner (or every other property), theses properties will be lazy loaded by Ebean.
Check out org.hibernate.criterion.Projections. Given a Criteria you can simply do the following:
criteria.setProjection(Projections.property("name"));

Using reserved JPQL keywords with JPA

I have an entity class called "Group" and NetBeans warns me "The entity table name is a reserved Java Persistence QL keyword".
A similar case would be the use of reserved SQL keywords.
Will this name be escaped? Would the use of a different table name solve the problem #Table(name="otherName"). Or should I rename the class?
Will this name be escaped?
There is nothing in the JPA spec that says so, if your provider does, this is provider specific.
Would the use of a different table name solve the problem #Table(name="otherName")
Obviously, it would (as long as you don't use another reserved keyword of course). But if you are using a JPA 2.0 provider, there is a standard way to get a db object name escaped, with double quotes:
#Table(name="\"Group\"")
In JPA 1.0, there is nothing standard, it depends on your JPA provider. For example, Hibernate uses backticks:
#Table(name="`Group`")
Or should I rename the class?
No. The table name of an entity defaults to the entity name but you can control it using the #Table annotation as we saw. There is thus no need to change the class name of your entity.
You don't have to rename the class - and you shouldn't - the name you have chosen reflects your domain in the best way, and you should not change it because of tool or framework limitations, in case the tool/framework provides a way to avoid the "clash". JPA provides such a way.

Categories