is there any option to execute hql query with procedure? - java

I have query in SQL like
select part_no, base_price, fn_get_ecom_item_new_price(Company_id, Part_No, Unit, Price, 'N') newPrice from ecom_prodmast
if there is an option to run the same query in hibernate? there is any other way to execute a select query with function in hibernate?

You can use session.get() method from Hibernate and the generated Java classes, then will look something like that:
SessionFactory factory=cfg.buildSessionFactory();
Session session=factory.openSession();
Transaction t=session.beginTransaction();
Economy e= (Economy) session.get(Economy.class, part_no ....);
t.commit();
session.close();
return e.getData();
The main Economy class should be configured to hold your data like part_no, base_price, fn_get_ecom_item_new_price, etc. of your ecom_prodmast table. That means first configure Hibernate and generate the classes, then use them. You can find examples on the internet on how to.
If you are using Eclipse is even simpler, because it exists a plug-in that does that for you.
If you want to access the procedure, that should also exist in the generated files and you call it as a simple function.

Yes,
use a native query.
Here is a link to Chapter 16. Native SQL.
For more information,
try a google search for "hibernate stored procedures mysql",
there are about a million hits.

Related

How to select schema at runtime using Hibernate?

I already have an existing code base, where schema(like db_1, db_2..) are created at run time.
We are currently using JdbcTemplate, using that its quite easy to append schema in the native SQL queries some thing like :-
sql = " Select * from "+schema+".user";
jdbcTemplate.query(sql, new UserMapper());
Now I want to know is how to provide schema to hibernate at runtime like I did with the jdbcTemplate?
What connection url should I provide in hibernate.cfg.xml so that it doesn't connects to a single schema rather whole database?
Any suggestions will be helpfull.
P.S: I am new to hibernate (So I might have missed something stupid)
I know of two options:
Use native SQL query binding results to JPA entities. Details here.
Use Hibernate multi-tenancy. Details here and here.
Although I haven't tried either.

Apache ibatis postgresql selectList how it it works

I have installed postgresql enterprise DB and created some tables
In one of the example. I see the following code.
import org.apache.ibatis.session.SqlSession;
.....
SqlSession session = sessionFactory.openSession();
.....
List list = session.selectList("findAllData-Data", params);
What it does? findAllData-Data means what? I have only created tables in postgresql, but I don't see the table name in above code
Check up the documentation for selectList
"findAllData-Data" is the unique identifier matching the statement to use. Statements are usually defined in some mapper .xml file or in newer versions in annotation of a class, so grep your code for findAllData-Data in order to find the definition.

Use two entity managers for one entity

The situation is the following: I have two databases Db1 and Db2, for which I have two EntityManagers em1 and em2 defined. Furthermore, I have the entity Person(int id, String name, Pet pet) mapped to the table persons(id, name) in the database Db1 and the entity Pet(int id, String name, Person owner) mapped to the table pets(id, name, person_id) in the database db2. The relation between Person and Pet is a #OneToOne realtion. At some point in the program, I would like to do something like this:
PersonDAO personDAO = db1DAOFactory.getPersonDAO();
Person person = personDAO.find(100);
System.out.println(person.getPet().getName());
There is no possibility to merge both databases. How can I tell Hibernate to use for the pet field the EntityManager em2? With Hibernate I use only annotations, no xml configuration.
Thank you very much!
Sorry but I think you can't. The question is answered by nakosspy:
Hibernate will create an SQL query for your HQL or Criteria query and this SQL will be sent through jdbc to the database. This means that hibernate does not support for what you are trying to do.
However, you can achieve the same result in some cases. Some databases give you the option to create an alias for a table that resides in a different database. So you will be able to write an SQL query that joins the two tables and execute it on the database.
We are doing that with DB2. If you can do that, it depends on your database.
I guess, that it would impossible if you have two different databases (example DB2 and MySQL) but if both databases are of the same vendor, then maybe it's achievable.
You should try to find more info in you database server's documentation.
If you want to see his original post check this link.
This is dependent on database features. If you are using Oracle database, You could achieve this by creating db link in database then map these entity through creating a view or a synonym in oracle database. Check your database features. Hope this helps.

Using native queries but maintaining database independence

With Spring JPA is there an easy way to use native queries but maintaining database independence, for example by using the query which fits best?
At the moment I do this by checking the currently set Dialect from the Environment and call the proper method of my Repository:
public Foo fetchFoo() {
if (POSTGRES_DIALECT.equals(env.getRequiredProperty("hibernate.dialect"))) {
return repo.postgresOptimizedGetFoo();
}
return repo.getFoo();
}
This works but I have the feeling that there is a better way or that I am missing something. Especially because (Spring) JPA allows it to use native queries quite easily but that breaks one of its big advantages: database independence.
As per my understanding, this can be achieved simply by using #Transactional(readOnly=false) and then instead of calling session.createQuery, one can use session.createSQLQuery, as provided in this example.
Your sql can be any of your native query.
Hope this works for you. :)
#Override
#Transactional(readOnly = false)
public Long getSeqVal() {
Session session = entityManager.unwrap(Session.class);
String sql = "SELECT nextval('seqName')";
Query query = session.createSQLQuery(sql);
BigInteger big = (BigInteger) query.list().get(0);
return big.longValue();
}
This is just an idea: I do not know whether it works or not:
My idea would be having subinterfaces, one normal Spring-Data-JPA-interface with all methods for one entiy (without native query hints). Than I would crate a subinterface for every database, that "override" the database specific native statements. (This intrface would be empty if there are no DB specific statements). Then I would try configure Spring-JPA with some profiles to load the right specific interface (for example by a class-name or package-name-pattern)
This seems like a way to complicated way to get queries to work.
If you really want to use optimized queries make it at least transparant for your code. I suggest using named queries and create an orm.xml per database (much like Spring Boot uses to load the schema.xml for a different database).
In your code you can simply do
public interface YourRepository extends JpaRepository<YourEntity, Long> {
List<YourEntity> yourQueryMethod();
}
This will look for a named query with the name YourEntity.yourQueryMethod. Now in your orm.xml add the named query (the default one and in another one the optimized one).
Then you need to configure your LocalContainerEntityManagerFactory to load the specific one needed. Assuming you have a property defining which database you use, lets name it database.type you could do something like the following
<bean class="LocalContainerEntityManagerFactoryBean">
<property name="mappingResources" value="classpath:META-INF/orm-${database.type}.xml" />
... other config ...
</bean>
This way you can keep your code clean of the if/then/else construct and apply where needed. Cleans your code nicely imho.

How does Hibernate generate sql string from session.get queries

I am using Hibernate 4.2.4 and I am interested to know how Hibernate translate a session.get call to an equivalent sql query that is eventually used to retrieve rows from database. I do not want to log the generated sql in console. I want to use the same sql query in my application. Something like below.
...
SessionFactory sessionFactory = configuration.buildSessionFactory(builder.buildServiceRegistry());
// I want the query string here
String query = sessionFactory.someUnknownMethod(Some Paramters);
Session session = sessionFactory.openSession();
// actual session.get query
Comment comment = (Comment) session.get(Comment.class, new Integer(1));
...
I have seen this thread for Criteria query -> How to get SQL from Hibernate Criteria API (*not* for logging).
I would like to know if similar procedure exists for session.get type queries.
I have also seen this thread -> get SQL from hibernate get
where the question is exactly same as mine, but the accepted solution talks about fetching statistics which, to my understanding, only accounts for the queries that have already been executed. Plus, from statistics I was able to catch hql/sql queries but not session.get queries.
I want to know if there is a way for a user to generate and use the sql even before the actual session.get gets executed (possibly by following the same path as hibernate).

Categories

Resources