hibernate entity-manager v/s hibernate jpa package which to use - spring

How do I configure hibernate?
If hibernate-entitymanager package is used for JPA then what good is of hibernate-jpa package. And I have seen that they use org.hibernate.ejb.HibernatePersistence class is used for JPA provider in persistence.xml which is in hibernate-entitymanager package.
In some cases, I have not seen the provider tag in persistence.xml. In this case which class is used?. Does Session class has EntityManager or implements it . And none of hibernate beans are specified in Spring-application context file directly. Instead spring.orm packages are used. So spring framework picks which class for JPA functionality.
org.springframework.orm.jpa.LocalEntityManagerFactoryBean picks which bean if provider tag is specified and if provider tag is not specified which bean is picked?

Hibernate JPA is a standard JPA implementation. See also these other questions about differences.
What's the difference between JPA and Hibernate?
Difference between Hibernate and Hibernate JPA
similarity and difference between jpa and hibernate
Session and EntityManager do approximately the same thing. EntityManager is the "new way."
I'm not clear on what your questions are about the persistence.xml file.

Thanks for reply but my Question was in which package the jpa implementation actually is . Is it in hibernate entitymanager.jar or hibernate-jpa2.1.jar . I found this fallowing link to be of little use
.https://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/ch01s02s01.html
but in this case in persistence.xml file contains org.hibernate.ejb.HibernatePersistence as jpa provider but this class is in hibernate-entitymanager package . But they also told that hibernate-jpa-2.0-api.jar is the JAR containing the JPA 2.0 API, it provides all the interfaces and concrete classes that the specification defines as public API. Said otherwise, you can use this JAR to bootstrap any JPA provider implementation. in this fallowing link
https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/configuration.html please could some one help me with this

Related

Spring boot Jpa is not working with Spring batch and spring integration

I am working with spring batch. I needed to add some jpa repositories. So previously i was using JDBCTemplate which was working fine.
But when I started working with JPA, the spring boot application could not find the repos. Which were there.
#Autowired
ClassLevelConfigRepo clcr;
I checked these things as the best practices.
Added #EnableJpaRepositories in springBoot application class.
Added #Repostiories to the repository interfaces.
extended the interfaces with JpaRepository<Account, String>
Added #Entity to the entity classes and defined the #Table and # Column annotations properly.
But I am still getting below error.
Field clcr in com.cloudtask.batchconfig.util.LhmUtility required a bean of type 'com.cloudtask.batchconfig.repo.ClassLevelConfigRepo' that could not be found.
I tried checking all the dependencies in pom.xml it was as per recommended. And I have all the tables defined properly in data base.
I was expecting the application to return the Autowired clcr object propely.
Edit 1 : spring boot application annotations
#SpringBootApplication
#ComponentScan({"com.cloudtask"})
#EnableAsync
#IntegrationComponentScan({"com.cloudtask"})
#EnableIntegrationManagement(defaultLoggingEnabled = "true")
#EnableJpaRepositories
#EntityScan
public class imclassApplication ```
When you work with Spring Data Jpa with those basic points you should also keep track of below points.
you have added spring-boot-starter-data-jpa in your pom.xml
you have added the entity and repo package below one level of the application package.
If you the package is at same level you should specify the exact package details in the annotation. in your case it should be like :
#EnableJpaRepositories("com.cloudtask.batchconfig.repo")
#EntityScan(basePackages = {"com.cloudtask.batchconfig.entity"})
Happy programming!

Should I annotate Spring Data Repositories with #Repository [duplicate]

I'm using Spring Data JPA repositories (like MyRepo extends JpaRepository) and it works without #Repository and without #EnableJpaRepositories annotations. Could someone explain why?
Probably you are using Spring Boot.
Spring Data repositories usually extend from the Repository or CrudRepository interfaces. If you use auto-configuration, repositories are searched from the package containing your main configuration class (the one annotated with #EnableAutoConfiguration or #SpringBootApplication) down.
Please check the Spring Boot Reference Documentation (v2.7.2) for more details.
you don't need #Repository to make use of Spring Data JPA.
The Interface extending the CrudRepository or JPARepository would work even without annotating it with #Repository.
The Core reason why you need to have this annotation in place is it makes unchecked exceptions thrown in the DAO layer eligible to be translated into Spring DataAccessException. Which in turn would be easier to work with. This is the important aspect of using #Repository
More details see this -> https://www.youtube.com/watch?v=z2re1MfWtz0&list=PLO0KWyajXMh4fGMvAw1yQ1x7mWayRcmX3&index=8&t=0s
For more information look into these class which is used to auto-configure Spring Data JPA Repositories:
JpaRepositoriesAutoConfigureRegistrar
Docs : http://www.atetric.com/atetric/javadoc/org.springframework.boot/spring-boot-autoconfigure/1.2.0.RELEASE/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfigureRegistrar.html
#EnableJpaRepositories
private static class EnableJpaRepositoriesConfiguration {
}

How to enable classpath scanning for #Entity classes in Spring boot

All my attempts at classpath scanning of #Entity classes failed in a Spring boot application. The most common solution I found on the web was this and it didn't work -
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.acme.domain");
#EntityScan on a #Configuration class did not work either.
All the entities and their mappings were listed in orm.xml and I had to move back to using #Entity annotations.
One solution that got me half way there was -
<persistence-unit>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>META-INF/orm.xml</mapping-file>
<class>com.acme.domain.Entity</class>
<shared-cache-mode>NONE</shared-cache-mode>
</persistence-unit>
This way I could use the #Entity annotations if I listed entity classes in persistence.xml.
The solution I didn't find while searching, which is listed on Spring Data JPA web page is this -
ClasspathScanningPersistenceUnitPostProcessor postProcessor = new ClasspathScanningPersistenceUnitPostProcessor("com.acme.domain");
entityManagerFactory.setPersistenceUnitPostProcessors(postProcessor);
Now the classpath scanning of #Entity classes is enabled. No mappings in orm.xml and no listing of entities in persistence.xml.
Sharing your code will help troubleshoot. Is there a github project you can share?
One thing to keep in mind is that SpringBoot takes an "opiniated" approach to everything. This means that for JPA, there is a "boot" way of doing things. Spring Tool Suite is your friend here.
Recommend checking this tutorial that shows you how to do JPA in Boot. Also, when using boot, I strongly recommend to start with a maven project setup from the Spring Initializer project.

Using Spring+Hibernate for testing purposes

I want to clarify my problem a bit more:
I understand the purposes of using SPring Framework (i.e. container-managed object lifecycle) and also Hibernate (using ORM between Javaobjects and relational database systems - impedance mismatch resolution).
I understand how we autowire an object and Spring takes over the creation and destruction of the object during runtime by looking at the applicationContext.xml file (in addition to persistence.xml file if using Hibernate or any other persistence provider).
What I want to do is the following:
I would like to implement my own shopping service. I already have entity (item) annotated with #Table, #Id, #Column, etc. to tell JPA that this is what will be stored in the database.
I already have a DAO interface (currently only add and delete methods) implemented by a DaoImpl class where I have done the following:
#Repository
#Transactional
public class MyShopDbDaoImpl implements MyShopDbDao {
// The following named unit will be in my persistence.xml file
// Which will be placed in src/main/resources/META-INF folder
#PersistenceContext(unitName="myShopDbDao")
private EntityManager em;
// Getters for em (simply returns em)
// Setters for em (simply assigns an em supplied in the args.)
// Other query method
}
I also have a ShopDbController controller class that uses:
#Autowired
// defined in the applicationContext.xml file
private MyShopDbDao myShopDbDaoImpl
What I am struggling with is the "Understanding" of EntityManagerFactory and EntityManager relationships along with how the transactions must be managed. I know that the following hierarchy is the main starting point to understand this:
Client talks to a controller.
Controller maps the request and gets the entitymanager to do queries and stuff to the database (either a test/local database with JUNIT test etc. or an actual SQL-type database).
What I do know is that transactions can be managed either manually (i.e. beginning, committing, and closing a session) or through Spring container (i.e. using bean defs in applicationContext.xml file). How can I get more information about the entitymanagers and entitymanagerfactory in order to setup my system?
I didn't find the online documentation from Oracle/Spring/Hibernate very helpful. I need an example and the explanation on the relationship between entitymanagerfactory, sessionfactory, entitymanager, and transactionmanager. Could someone please help me with this?
I don't need people to hold my hand, but just put me in a right direction. I have done Spring projects before, but never got to the bottom of some stuff. Any help is appreciated.
EntityManagerFactory will obtain java.sql.Connection objects, through opening/closing new physical connections to the database or using a connection pool (c3p0, bonecp, hikari or whatever implementation you like). After obtaining a Connection, it will use it to create a new EntityManager. The EntityManager can interact with your objects and your database using this Connection and can manage the transaction through calling EntityManager#getTransaction and then calling EntityTransaction#begin, EntityTransaction#commit and EntityTransaction#rollback that internally works with Connection#begin, Connection#commit and Connection#rollback respectively. This is plain vanilla JPA and Spring has nothing to do up to this point.
For transaction management, Spring helps you to avoid opening/closing the transactions manually by using a transaction manager, specifically a class called JpaTransactionManager. This transaction manager will make use of your EntityManagerFactory to open and close a transaction for the EntityManager created for a set of operations. This can be done either using XML configuration or #Transactional annotation on your classes/methods. When using this approach, you won't directly work with your specific classes anymore, instead Spring will create proxies for your classes using cglib and make use of the transaction manager class to open the transaction, call your specific method(s) and execute a commit or rollback at the end, depending on your configuration. Apart of this, Spring provides other configurations like read-only transactions (no data modification operation allowed).
Here's a basic configuration of the elements explained above using Spring/Hibernate/JPA:
<!--
Declare the datasource.
Look for your datasource provider like c3p0 or HikariCP.
Using most basic parameters. It's up to you to tune this config.
-->
<bean id="jpaDataSource"
class="..."
destroy-method="close"
driverClass="${app.jdbc.driverClassName}"
jdbcUrl="${app.jdbc.url}"
user="${app.jdbc.username}"
password="${app.jdbc.password}" />
<!--
Specify the ORM vendor. This is, the framework implementing JPA.
-->
<bean id="hibernateVendor"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
showSql="false"/>
<!--
Declare the JPA EntityManagerFactory.
Spring provides a class implementation for it.
-->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
persistenceXmlLocation="classpath*:META-INF/persistence.xml"
persistenceUnitName="hibernatePersistenceUnit"
dataSource-ref="jpaDataSource"
jpaVendorAdapter-ref="hibernateVendor"/>
<!--
Declare a transaction manager.
Spring uses the transaction manager on top of EntityManagerFactory.
-->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager"
entityManagerFactory-ref="entityManagerFactory"/>
From what i see, your em reference should be a functioning proxy object to your database (this EntityManager is the thing that should be a spring bean, having configured everything, like DB url, driver, etc. Apart from this none of your code should depend on what DB you have). You don't need to know about the classes you mention (entitymanagerfactory sessionfactory transactionmanager). Easy example is:
List<MyBean> bean = (List<MyBean>)em.createNamedQuery("select * from mydb").getResultList();
It should be this easy to run a select * query and get your MyBean typed objects straight ahead, without any explicit conversion by you (this is what hibernate is for).
Similar for insert:
em.persist(myBean);
where myBean is something annotated for Hibernate.
Briefly about transactions, i found best to annotate #Transactional on service METHODS (you did it on a whole dao).
To be very very general:
an entitymanagerfactory is an object responsible of the creation of the entitymanager and it comes from the JPA specifications.
SessionFactory is the hibernate implementation of entitymanagerfactory
session is the hibernate implementation of entitymanager
A transacation manager is an object who manages transaction when you want to define a transaction manually.
So if you want to use hibernate, use SessionFactory and session. And if you want you to stay "generic" use the EntityManagerFactory.
http://www.javabeat.net/jpa-entitymanager-vs-hibernate-sessionfactory/
http://www.theserverside.com/tip/How-to-get-the-Hibernate-Session-from-the-JPA-20-EntityManager

When to use Spring #Autowire annotation

Recently I had discussion with my friend regarding usage of Spring #Autowire annotation on entity(JPA) classes.
In our project we are using #Autowire annotaion to inject Entity but my friend suggesting not to use #Autowire annotaions on entity classes. When I asked why? He dont have the proper answer for that. So i just wanted to know are there any disadvantages using #Autowire annotaion on entity classes.
Also please explain when to go for #Autowire annotaion or not with example.
Thank in advance.
#Entity and #Autowire are not interchangeable.
#Entity annotation indicates that the JavaBean is a persistent entity.This is actually a JPA annotation and not a Spring Annotation.
#Entity will be used in the sessionFactory by the packagesToScan poroerty.
#Autowired: inject a resource by-type, i.e. by the class or by the interface of the annotated field or contractor. See my answer Inject and Resource and Autowired annotations
#Autowired is used to inject dependencies as an alternative to setting it via xml configurations
Maybe this answer will help you understand
Hibernate - spring annotated entities not scanned from within jar
UPDATE:
Following the comment bellow:
Company is your domain object, so you don't need to use spring in this case.
<bean id="company" class="xxx.Company"/>
The above will return the same instance with #autowire.
Even if you switch to scope="prototype" I don't see any reason to use spring for that.
You should have a service that will be used to CRUD company e.g.
CompanyService, this service will be a single tone so you will use #Autowire to inject it to the controller and it will use your JPA framework to implement CRUD's
To create a new company you will use:
Company c = new Company //this probably will be binded from your ui form
companyServic.saveOrUpdate(c);
See the following answer spring rest service - hibernate dao - annotations - pojo - namedqueries.
For common practice of DAO and services.
#Autowire is an annotation used to perform a dependency injection, its almost similar to the standard #Inject you can take a look at the spring reference manual to see the difference between those two annotations.
#Entity is a part of the jpa framework its used to mark a class as persistent, spring does not implement an equivalent annotation.

Resources