Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get JPA configured with Spring 3?

I have been reading spring's documentation, but I must say it is a bit confusing, giving several different option on how to configure JPA.

What is the best way, and how, to get JPA 2 (with hibernate) configured with spring 3? If you have an example of pom, web.xml, applicationContext.xml, and any needed java code, could you please kindly post it as well.

thanks!

like image 497
Emerson Avatar asked Mar 21 '11 01:03

Emerson


3 Answers

I use EclipseLink, but configuration must be very similar. Here you have most important parts.

pom.xml:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${org.springframework-version}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.0.1</version> 
    </dependency>
    <dependency> 
        <groupId>javax.persistence</groupId>
        <artifactId>javax.persistence</artifactId>
        <version>2.0.0</version>
    </dependency>

persistence.xml:

    <?xml version="1.0" encoding="UTF-8" ?>
    <persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">

    <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL" />

</persistence>

applicationContext-dao.xml:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath:persistence.xml" />
    <property name="persistenceUnitName" value="persistenceUnit" /> 
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaPropertyMap">
        <props>
            <prop key="eclipselink.weaving">false</prop>
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

User.java:

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer id;

    private String name;

    // Getters and setters

}

UserDao.java:

@Repository
public class JpaUserDao implements UserDao {

    @PersistenceContext
    private EntityManager em;

    @Override
    public Item get(Integer id) {
        return em.find(User.class, id);
    }
}

UserService.java:

@Service 
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Transactional
    @Override
    public User getUser(Integer id) {
        return userDao.get(id);
    }

}

Hope it helps.

like image 157
sinuhepop Avatar answered Oct 23 '22 18:10

sinuhepop


Alternatively Spring 3+ and JPA 2.0 can be integrated with the help of dynamic proxies.

You can find all the documentation and download example here

In this case interfaces with named JPA queries are used to execute queries. Interfaces are treated as ordinary Spring beans with the help of dynamic proxies. They can be injected (or autowired) into any other beans the same way.

Also queries can be located in separate orm-mapping.xml files and split up by domain (or at your convenience). That gives a high flexibility and maintainability to persistent layer.

public interface OrganisationQueries {

        @Query(named = "find.organisation.by.role.id")
        public Organisation findOrganisationByRoleId(Long roleId);

        @Query(named = "find.all.organisations")
        public List<Organisation> findAllOrganisations();
    }
    public class OrganisationServiceImpl implements OrganisationService {
        @PersistenceContext
        private EntityManager em;
        @Autowired
        private OrganisationQueries organisationQueries;
        @Override
        public Organisation findOrganisationByRoleId(Long roleId) {
            return organisationQueries.findOrganisationByRoleId(roleId);
        }
        @Override
        public List<Organisation> findAllOrganisations() {
            return organisationQueries.findAllOrganisations();
        }
    }

   <entity-mappings xmlns="..." version="1.0">
      <named-query name="find.organisation.by.role.id">
          <query><![CDATA[
                    select r.organisation from Role r
                    where r.id =?1
          ]]></query>
      </named-query>
      <named-query name="find.all.organisations">
           <query><![CDATA[
                   select org from Organisation org
                    left join fetch org.organisationType
           ]]></query>
       </named-query>
   </entity-mappings>
like image 35
Denis Skarbichev Avatar answered Oct 23 '22 16:10

Denis Skarbichev


I would suggest you take a look at Spring Roo, it creates a Spring web project together with the pom and all configuration files needed (e.g. JPA). And if you don't like Roo you can drop it and threat the project as usual Spring Web application. IMHO the fastest way to get a initial project setup.

like image 40
moritz Avatar answered Oct 23 '22 17:10

moritz