简体   繁体   中英

Setting up Spring with JPA and Maven

I'm new to Spring and am trying to set up a project using JPA and Maven . I can't seem to figure out the right configuration between the different xml files needed. I've seen that many questions have been posted on this, and I've tried using code from the posted solutions, but I keep getting different errors all leading up to IllegalStateException: Failed to load ApplicationContext in the JUnit test I'm trying to run.

Here is my persistence.xml which I've placed in the META-INF folder of src/main/resources :

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

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

Here is the production-application.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost/wellness;shutdown=true"/>
    <property name="username" value="un"/>
    <property name="password" value="pw"/>
</bean>

<!-- Transaction Manager for the project -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" autowire="byType"/>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="false"/>
            <property name="generateDdl" value="true"/>
            <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
        </bean>
    </property>
</bean>

<tx:annotation-driven/>

<context:component-scan base-package="com.kylewalker.wellness"/>

Here is the POM , which might be greatly bloated because I've had a hard time figuring out exactly which dependencies are necessary and which are not:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.kylewalker</groupId>
  <artifactId>wellness</artifactId>
  <version>1.0</version>
  <packaging>war</packaging>
  <name>wellness</name>
  <description>A business magagement tool for a wellness organization offering services such as massage, nutrition counseling, etc.</description>

  <dependencies>
<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>org.eclipse.persistence.jpa</artifactId>
    <version>2.5.0</version>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>

<!--     
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>servlet-api</artifactId>
    <version>6.0.37</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
</dependency>
-->

<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.0.3.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.0.3.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.0.3.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>4.0.3.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>4.0.3.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.0.3.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>4.3.4.Final</version>
</dependency>

<dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.0-api</artifactId>
    <version>1.0.1.Final</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.30</version>
</dependency>

  </dependencies>

  <build>
  <plugins>
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat6-maven-plugin</artifactId>
      <version>2.1</version>
    </plugin>

    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.1</version>
    </plugin>

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.5.1</version>
        <configuration>
            <source>1.7></source>
            <target>1.7</target>
        </configuration>
    </plugin>

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-war-plugin</artifactId>
      <version>2.2</version>
      <configuration>
        <failOnMissingWebXml>false</failOnMissingWebXml>
      </configuration>
    </plugin>

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-failsafe-plugin</artifactId>
      <version>2.12.4</version>
      <executions>
        <execution>
            <id>integration-test</id>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
        </execution>
      </executions>
    </plugin>

    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.2.1</version>
        <executions>
            <execution>
                <goals>
                    <goal>java</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <mainClass>com.kylewalker.wellness.Main</mainClass>
        </configuration></plugin>
  </plugins>
</build>
</project>

Here is my Customer class:

package com.kylewalker.wellness.domain;

import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
public class Customer {

@Id @GeneratedValue
private Long customerId;

private String firstName;
private String middleName;
private String lastName;
@Temporal(TemporalType.DATE)
private Date dateOfBirth;
private Address address;
private String phone;
private String email;

// argument-ed constructor, getters and setters

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result
            + ((customerId == null) ? 0 : customerId.hashCode());
    result = prime * result
            + ((firstName == null) ? 0 : firstName.hashCode());
    result = prime * result
            + ((lastName == null) ? 0 : lastName.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Customer other = (Customer) obj;
    if (customerId == null) {
        if (other.customerId != null)
            return false;
    } else if (!customerId.equals(other.customerId))
        return false;
    if (firstName == null) {
        if (other.firstName != null)
            return false;
    } else if (!firstName.equals(other.firstName))
        return false;
    if (lastName == null) {
        if (other.lastName != null)
            return false;
    } else if (!lastName.equals(other.lastName))
        return false;
    return true;
}
    //toString()
}

Here is my CustomerDao :

package com.kylewalker.wellness.dataaccess;

import java.util.List;

import com.kylewalker.wellness.domain.Customer;

public interface CustomerDao {

public void create(Customer customer);
public Customer getById(String customerId) throws RecordNotFoundException;
public List<Customer> getByName(String lastName, String firstName) throws RecordNotFoundException;
public void update(Customer customerToUpdate) throws RecordNotFoundException;
public void delete(Customer oldCustomer) throws RecordNotFoundException;
public List<Customer> getAllCustomers();
}

Here is the implementation of my CustomerDao :

package com.kylewalker.wellness.dataaccess;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import com.kylewalker.wellness.domain.Customer;

@Repository
public class CustomerDaoImpl implements CustomerDao {

@PersistenceContext
private EntityManager em;

public void create(Customer customer) {
    em.persist(customer);
}

public Customer getById(String customerId) throws RecordNotFoundException {
    return (Customer)em.createQuery("select customer from Customer as customer where customer.customerId=:customerId").setParameter("customerId", customerId).getSingleResult();
}

public List<Customer> getByName(String lastName, String firstName) throws RecordNotFoundException {
    return em.createQuery("select customer from Customer as customer where customer.firstName=:firstName and customer.lastName=:lastName").setParameter("firstName", firstName).setParameter("lastName", lastName).getResultList();
}

public void update(Customer customerToUpdate)
        throws RecordNotFoundException {
    // TODO add code here
}

public void delete(Customer oldCustomer) throws RecordNotFoundException {
    Customer foundCustomer = em.find(Customer.class, oldCustomer.getCustomerId());
    em.remove(foundCustomer);
}

public List<Customer> getAllCustomers() {
    return em.createQuery("select customer from Customer as customer").getResultList();
}

}

Here is my CustomerService :

package com.kylewalker.wellness.services;

import java.util.List;
import com.kylewalker.wellness.domain.Customer;

public interface CustomerService {

public void newCustomer(Customer newCustomer);
public void updateCustomer(Customer changedCustomer) throws CustomerNotFoundException;
public void deleteCustomer(Customer oldCustomer) throws CustomerNotFoundException;  
public Customer findCustomerById(String customerId) throws CustomerNotFoundException;
public List<Customer> findCustomersByName (String lastName, String firstName) throws CustomerNotFoundException;
public List<Customer> getAllCustomers();
}

Here is the implementation of my CustomerService :

package com.kylewalker.wellness.services;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.kylewalker.wellness.domain.Customer;
import com.kylewalker.wellness.dataaccess.CustomerDao;
import com.kylewalker.wellness.dataaccess.RecordNotFoundException;

@Transactional
@Service
public class CustomerServiceImpl implements CustomerService {

private CustomerDao dao;

@Autowired
public CustomerServiceImpl(CustomerDao dao) {
    this.dao = dao;
}

public void newCustomer(Customer newCustomer) {
    dao.create(newCustomer);
}

public void updateCustomer(Customer changedCustomer)
        throws CustomerNotFoundException {
    // TODO Auto-generated method stub

}

public void deleteCustomer(Customer oldCustomer)
        throws CustomerNotFoundException {
    try {
        dao.delete(oldCustomer);
    } catch (RecordNotFoundException e) {
        throw new CustomerNotFoundException();
    }
}

public Customer findCustomerById(String customerId)
        throws CustomerNotFoundException {
    // TODO Auto-generated method stub
    return null;
}

public List<Customer> findCustomersByName(String lastName, String firstName)
        throws CustomerNotFoundException {
    try {
        return dao.getByName(lastName, firstName);
    } catch (RecordNotFoundException e) {
        throw new CustomerNotFoundException();
    }
}

public List<Customer> getAllCustomers() {
    return dao.getAllCustomers();
}

}

Here is my JUnit test:

package com.kylewalker.wellness.testing;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import com.kylewalker.wellness.domain.Customer;
import com.kylewalker.wellness.services.CustomerService;
import com.kylewalker.wellness.services.CustomerNotFoundException;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/production-application.xml"})
@Transactional
public class TestCreateNewCustomer {

@Autowired
private CustomerService customers;

@Test
public void testCreateCustomer() {
    String firstName = "James";
    String lastName = "Smith";
    String email = "jsmith@gmail.com";
    Customer newCustomer = new Customer(firstName, lastName, email);
    customers.newCustomer(newCustomer);

    Customer foundCustomer = null;
    List<Customer> allCustomersByThatName = null;

    try {
        allCustomersByThatName = customers.findCustomersByName(lastName, firstName);
        foundCustomer = allCustomersByThatName.get(0);
        assertEquals("The customer returned is the wrong one.", newCustomer, foundCustomer);
    } catch (CustomerNotFoundException e) {
        fail("No customer was found when one should have been found.");
    }
}
}

And finally... here is the trace I get when I run the test:

java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:319)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeDaoImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory com.kylewalker.wellness.dataaccess.EmployeeDaoImpl.sessionFactory; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.hibernate.SessionFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:121)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:250)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
... 25 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory com.kylewalker.wellness.dataaccess.EmployeeDaoImpl.sessionFactory; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.hibernate.SessionFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
... 41 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.hibernate.SessionFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 43 more

It looks like it's trying to map to a Referral object..

Caused by: org.hibernate.AnnotationException: No identifier specified for entity: com.kylewalker.wellness.domain.Referral

which looks to be the one file you didn't provide :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM