Reputation: 13
I'm doing a GWTP project and use Spring Data JPA for a connection with an oracle database. I've read several tutorials in which a repository interface is used directly without the use of implementation. It was @Autowired where needed and it worked fine. I've tried to use the same strategy but it seems the @Autowired annotation is not working at all.
Here is my Repository :
@Repository
public interface BugRepository extends JpaRepository<Bug, Long> {
List<Bug> findAll();
.....
}
I try to inject it with @Autowired in my service implementation (I use RESTful services) :
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/bugs")
@Component
public class BugServiceImpl{
@Autowired
private BugRepository bugRepository;
@GET
@Path("/findAll")
public List<Bug> findAll() {
return bugRepository.findAll();
}
}
Here is my Entity :
@Entity
@Table(name = "BUGS")
@SequenceGenerator(name = "BUG_SEQUENCE", sequenceName = "BUG_SEQUENCE")
public class Bug implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "BUG_SEQUENCE")
@Column(name="BUG_ID")
private Long bugId;
@Column(name="BUG_NAME")
private String bugName;
@OneToOne
@PrimaryKeyJoinColumn
@Column(name="CREATED_BY")
private User createdBy;
@OneToOne
@PrimaryKeyJoinColumn
@Column(name="ASSIGNED_TO")
private User assignedTo;
@Column(name="CREATION_DATE")
private Date creationDate;
@Column(name="LAST_UPDATE_DATE")
private Date lastUpdateDate;
@Column(name="BUG_COMMENT")
private String bugComment;
@OneToOne(cascade = CascadeType.ALL, optional = false, fetch = FetchType.EAGER, orphanRemoval = true)
@PrimaryKeyJoinColumn
@Column(name="PRIORITY_ID")
private Priority priority;
@OneToOne
@PrimaryKeyJoinColumn
private Status status;
public Bug() {
}
}
I also have applicationContext.xml and persistence.xml in main/resources/META-INF. Here is my applicationContext.xml :
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
<context:component-scan base-package="com.edu" />
<jpa:repositories base-package="com.edu.server.repositories" />
<context:annotation-config />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="***"/>
<property name="username" value="***"/>
<property name="password" value="***"/>
</bean>
<!-- EntityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:packagesToScan="com.edu.shared.entity"
p:dataSource-ref="dataSource"
>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="true" />
<property name="showSql" value="false" />
</bean>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
My persistence.xml :
<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/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<!-- oracle -->
<persistence-unit name="oracle">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.edu.server.service.BugServiceImpl</class>
<class>com.edu.server.repositories.BugRepository</class>
<class>com.edu.shared.entity.Bug</class>
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver" />
<property name="hibernate.connection.url" value="***" />
<property name="hibernate.connection.username" value="***" />
<property name="hibernate.connection.password" value="***" />
<property name="hibernate.flushMode" value="FLUSH_AUTO" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
And finally the exception I get is :
java.lang.NullPointerException
com.edu.server.service.BugServiceImpl.findAll(BugServiceImpl.java:39)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
...
When I debug the code and put a breakpoint to the autowired repository it appears to be null so I suppose it's not injected properly and that's why invoking the method findAll fires the NullPointerException. So, why do you think the @Autowired annotation is not working?
Upvotes: 0
Views: 11040
Reputation: 13
I want to thank all for the help. I solved my problem. There were problems in my configuration files.
First of all, I really didn't need any persistence.xml because I've created a dataSource bean in my applicationContext.xml which contains all of the needed information regarding the connection with my database. You shouldn't mix the both things, I suppose.
Secondly, you should properly configure the link between Spring and Jersey. I had to add some new dependencies in my pom.xml which were needed for linking Spring and Jersey (there is a jersey-spring3 dependency which I didn't know existed). So, now all of the dependencies I use, concerning Spring and Jersey are these:
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>${javax.rs.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.fusesource.restygwt</groupId>
<artifactId>restygwt</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>1.1.2.RELEASE</version>
<type>pom</type>
<!--<scope>import</scope>-->
<scope>compile</scope>
</dependency>
<!-- DataSource (HikariCP) -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.2.5</version>
</dependency>
<!-- JPA Provider (Hibernate) -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.8.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.10.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>12.1.0.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.8.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>${jersey.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
</exclusions>
</dependency>
In addition, I had to configure my web.xml so that Jersey could read the applicationContext.xml. Without configuring my web.xml the applicationContext.xml was useless and that's why the annotations and the connection with the database didn't work. Here is my web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:META-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.edu</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
As far as I understood the ContextLoadListener
makes sure the web configuration "listens" for other configuration xml files and that's how the applicationContext.xml is now read and used. And with these settings
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.edu</param-value>
I make sure that my packages would be scanned for @Provider and @Path annotations and without these piece of my code my services would not be active. More about this Provider Packages setting can be read here :
I hope my issue and this answer are useful for all with similar configuration problems.
Upvotes: 0
Reputation: 4324
First problem that i see is you have annotated your interface with @Repository
You shouldn't do that, but as follows:
//no annotation here
public interface BugRepository extends JpaRepository<Bug, Long> {
List<Bug> findAll();
.....
}
Secondly, make sure your BugRepository
interface is in the package below, or else it wont work:
<jpa:repositories base-package="com.edu.server.repositories" />
Third thing i noticed is in your persistance.xml
, you have noted NOT only @Entity
beans, but @Service
and a @Repository
. You are supposed to only have @Entity
beans (which are to be managed)
Lastly, you seem to be mixing Spring
and Jersey
, so make sure you have your Spring container (application/web context) properly set up, so it can manage (inject) your beans/repos/services.
Upvotes: 0
Reputation: 596
I think you're mixing two ways of Spring/JPA configuration. Last time when i configured Spring/JPA project with XML I use only DataSource
bean without persistence.xml
configuration for connection to the database. I can suggest you to read the official documentation of Spring Data. The community has one of the best documentation.
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/orm.html
Upvotes: 1