Spring REST + Hibernate

0

Witam,
Mam problem z podłączeniem Hibernate do REST w springu. Przy próbie odczytania listy użytkowników dostaję:
SEVERE [http-apr-8080-exec-22] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [dispatcher] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause java.lang.NullPointerException

Pewnie mam jakieś błędy w konfiguracji ale nie wiem jakie.

Poniżej zamieszczam fragmenty plików HelloWorldRestController, UserDAO, UserDAOImpl, User, UserService, UserServiceImpl oraz servlet-context.xml:

 
@RestController
public class HelloWorldRestController {

	@Autowired
	private UserService userService;  //Service which will do all data retrieval/manipulation work

	@RequestMapping(value = "/user/", method = RequestMethod.GET)
	public ResponseEntity<List<User>> listAllUsers() {
		List<User> users = userService.listUsers();
		if(users.isEmpty()){
			return new ResponseEntity<List<User>>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
		}
		return new ResponseEntity<List<User>>(users, HttpStatus.OK);
	}
}

public interface UserDAO {
	public List<User> listUsers();
}


@Repository("userDAO")
public class UserDAOImpl implements UserDAO {
	
	private static final Logger logger = LoggerFactory.getLogger(UserDAOImpl.class);

	private SessionFactory sessionFactory;
	
	public void setSessionFactory(SessionFactory sf){
		this.sessionFactory = sf;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<User> listUsers() {
		Session session = this.sessionFactory.getCurrentSession();
		System.out.println("SDAF");
		List<User> userList = session.createQuery("from user").list();
		for(User user : userList){
			logger.info("Person List::"+user);
		}
		return userList;
	}
}


@Entity
@Table(name="USER")
public class User {

	@Id
	@Column(name="id")
	@GeneratedValue(strategy=GenerationType.AUTO)
	private int id;
	
	private String name;
	
	private int age;
	
	private double salary;

	public User(){
		id=0;
	}
	
	public User(int id, String name, int age, double salary){
		this.id = id;
		this.name = name;
		this.age = age;
		this.salary = salary;
	}
	
	public long getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (id ^ (id >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (id != other.id)
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", age=" + age
				+ ", salary=" + salary + "]";
	}


}

public interface UserService {
	public List<User> listUsers();
}


@Service("userService")
@Transactional
public class UserServiceImpl implements UserService{

	private UserDAO userDAO;

	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

	@Override
	@Transactional
	public List<User> listUsers() {
		return this.userDAO.listUsers();
	}
}


<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<beans:property name="url"
			value="jdbc:mysql://localhost:3306/user" />
		<beans:property name="username" value="root" />
		<beans:property name="password" value="admin" />
	</beans:bean>

	<!-- Hibernate 4 SessionFactory Bean definition -->
	<beans:bean id="hibernate4AnnotatedSessionFactory"
		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<beans:property name="dataSource" ref="dataSource" />
		<beans:property name="annotatedClasses">
			<beans:list>
				<beans:value>com.websystique.springmvc.controller.model.User</beans:value>
			</beans:list>
		</beans:property>
		<beans:property name="hibernateProperties">
			<beans:props>
				<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</beans:prop>
				<beans:prop key="hibernate.show_sql">true</beans:prop>
				<beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
			</beans:props>
		</beans:property>
	</beans:bean>
	
	<beans:bean id="userDAO" class="com.websystique.springmvc.dao.UserDAOImpl">
		<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
	</beans:bean>
	<beans:bean id="userService" class="com.websystique.springmvc.service.UserServiceImpl">
		<beans:property name="userDAO" ref="userDAO"></beans:property>
	</beans:bean>
	<context:component-scan base-package="com.websystique.springmvc.controller" />
	
	<tx:annotation-driven transaction-manager="transactionManager"/>

	<beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
	</beans:bean>

 
0

uzyj spring data oraz javowych konfiguracji.

1

Bo robisz cuda na kiju. Deklarujesz beany w xmlu ORAZ oznaczasz klasy jako @Service i @Repository i masz component-scan. To oznacza ze tworzysz finalnie DWA ZESTAWY beanów, jeden z adnotacji a drugi z xmla. Tylko że zależności dla tych klas wstrzykujesz tylko z XMLa w efekcie te "adnotacyjne" mają nulle zamiast swoich zależności.

Wywal te beany z xmla a zależności w nich oznacz jako autowired/inject.

Moja rada: zacznij może naukę od podstaw, bo teraz zupełnie nie rozumiesz co robisz. Skopiowałeś skądś kod i nie masz pojęcia co ten kod robi.

0

Poczytaj jak działa context component scan i co to autowired
Ja robie tak że swoje klasy oznaczam jako @service, @repository, @component i tych już nie deklaruje w xml,a w xml reszte (np. datasource,sessionFactory itp)
Używam autowired i wtedy dzięki context component scan spring wstrzykuje w miejsce gdzie są adnotacje autowired:

 
@Repository(value = "categoryDAO")
public class CategoryDAOImpl implements CategoryDAO{
...
}
 
@Service (value = "categoryService")
@Transactional(readOnly = true)
public class CategoryServiceImpl implements CategoryService{
	@Autowired
	CategoryDAO categoryDAO;
...
}

Oczywiście autowired działa też z xml-beanami

 
 <bean id="jdbcTemplate"
    	class="org.springframework.jdbc.core.JdbcTemplate">
    	<property name="dataSource" ref="dataSource"></property>
    </bean>
 
@Repository(value = "expenseDAO")
public class ExpenseDAOImpl implements ExpenseDAO {
	@Autowired
	private JdbcTemplate jdbcTemplate;
...
}

Ważne żeby bean był albo w xml albo w klasie

1 użytkowników online, w tym zalogowanych: 0, gości: 1