2016-05-05 11 views
0

Ich bin ein einfaches Hibernate-Projekt mit Spring IoC und konfrontiert dumme NPE während der Injektion. Beide Xml und Java-Stil Spring-Konfigurationen erwies sich als ineffizient und ich steckte. Jede Hilfe wird geschätzt.NullPointerException während der Initialisierung von Spring Bean

Exception I erfüllen:

Exception in thread "main" java.lang.NullPointerException 
at com.phoneBook.DAO.ContactDAOImpl.getSession(ContactDAOImpl.java:22) 
at com.phoneBook.DAO.ContactDAOImpl.save(ContactDAOImpl.java:28) 
at com.phoneBook.DAO.ContactDAOImpl.main(ContactDAOImpl.java:61) 

Meine Anwendung-config.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:aop="http://www.springframework.org/schema/aop" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd 
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> 

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

    <tx:annotation-driven transaction-manager="transactionManager" /> 

    <bean id="propertyConfigurer" 
     class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
     <property name="location" value="classpath:properties/database.properties" /> 
    </bean> 

    <bean id="dataSource" 
     class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="${jdbc.driverClassName}" /> 
     <property name="url" value="${jdbc.url}" /> 
     <property name="username" value="${jdbc.username}" /> 
     <property name="password" value="${jdbc.password}" /> 
    </bean> 

    <bean id="sessionFactory" 
     class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="packagesToScan" value="com.phoneBook.entities" /> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
       <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> 
       <prop key="hibernate.flushMode">${hibernate.flushMode}</prop> 
       <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> 
      </props> 
     </property> 
    </bean> 

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

    <bean id="persistenceExceptionTranslationPostProcessor" 
     class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /> 
</beans> 

applikations context.xml

<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" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 

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

</beans> 

Contact.class

package com.phoneBook.entities; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Table; 

@Entity 
@Table(name="contacts") 
public class Contact { 
@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) 
@Column(name="contact_id") 
private int id; 

@Column(name="contact_surname", nullable = false, length = 20) 
private String surname; 

@Column(name="contact_name", nullable = false, length = 20) 
private String name; 

@Column(name="contact_patname", nullable = false, length = 20) 
private String patName; 

@Column(name="contact_mobtel", unique = true, nullable = false, length = 12) 
private String telNumberMob; 

@Column(name="contact_hometel", length = 12) 
private String telNumberHome; 

@Column(name="contact_address", length = 30) 
private String address; 

@Column(name="contact_email", length = 20) 
private String email; 

    public Contact(){} 

    public Contact(String surname, String name, String patName, String mobTel, String homeTel, String address, String email){ 
     this.surname = surname; 
     this.name = name; 
     this.patName = patName; 
     this.telNumberMob = mobTel; 
     this.telNumberHome = homeTel; 
     this.address = address; 
     this.email = email; 
    } 
    //getters and setters 

} 

und ContactDAOimpl.java

package com.phoneBook.DAO; 

import java.util.List; 

import javax.transaction.Transactional; 

import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.criterion.Restrictions; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Repository; 

import com.phoneBook.entities.Contact; 

@Repository 
@Transactional 
public class ContactDAOImpl implements ContactDAO { 
    @Autowired 
    private SessionFactory sessionFactory; 

    protected Session getSession(){ 
     return sessionFactory.getCurrentSession(); 
    } 

    @Override 
    public void save(Contact cont) { 
     if(cont.getId()==0) 
      getSession().persist(cont); 
     else 
      getSession().update(cont); 
    } 

    @Override 
    public Contact getById(int id) { 
     Contact contact = (Contact)getSession().createCriteria(Contact.class).add(Restrictions.eq("id",id)).uniqueResult(); 
      return contact; 
    } 

    @Override 
    public List<Contact> getAll() { 
     @SuppressWarnings("unchecked") 
     List<Contact> allContacts = sessionFactory.getCurrentSession().createCriteria(Contact.class).list(); 
     return allContacts; 
    } 

    @Override 
    public int remove(Contact cont) { 
     getSession().delete(cont); 
     return cont.getId(); 
    } 

    public static void main(String args[]){ 
     ContactDAOImpl dao = new ContactDAOImpl(); 
     Contact testContact = new Contact("name", "surname", "patname", "380442322233", "380442322233", 
       "address", "[email protected]"); 
     dao.save(testContact); 
    } 

} 

Meine Abhängigkeiten:

Dependencies

Antwort

0

Sie können es nicht tun

ContactDAOImpl dao = new ContactDAOImpl();

  1. Siesollte hinzufügenan die application-config.xml.
  2. erstellen Feder Zusammenhang als @hasnae vorgeschlagen

    ApplicationContext context = new ClasspathApplicationContext("application-config.xml");

  3. Get contactDao Form der Kontext

    ContactDAO contactDao = (ContactDAO) context.getBean("contactDao");

als eine schnelle Lösung, Sie sessionFactory Form erhalten können die context und setzen Sie es auf die (Es ist nur für eine Darstellung, wie Sie Sie werden keine Transaktionen und save() wird nicht funktionieren)

ContactDAOImpl contactDao = new ContactDAOImpl(); 
contactDao.setSessionFactory((SessionFactory)context.getBean("sessionFactory")); 

Sie benötigen einen Setter für es hinzuzufügen.

+0

Aber ich hielt und entsprechende Annotationen für ausreichend, um Kontext ohne expliziten Aufruf aufzurufen. Ein weiteres Problem ist die Transaktion: Obwohl ich die Klasse als @Transactional markiert habe, sehe ich immer noch die "No Session found for current thread". Was ist der Ausweg? – ryzhman

+0

'' funktioniert für alle verschachtelten Beans mit Ausnahme der ersten Root-Bean. Spring weiß nichts über Ihren Code und kann keine Session-Factory mit 'ContactDAOImpl dao = new ContactDAOImpl()' automatisch aktualisieren. Sie müssen 'dao' aus einem Spring-Kontext abrufen, damit Spring eine Transaktionsunterstützung dafür hinzufügt. –

+0

Aber wenn ich neue ContactDAOImpl() erstellen und es hat eine injizierte Sitzung, warum sollte Spring nicht tun, was es soll? Und könnten Sie bitte Ihre Idee über "erste Root-Bean" ausarbeiten: Wenn ich eine DAO-Instanz (einschließlich der Injected Session-Eigenschaft) aus der Service-Ebene einfüge, muss ich keinen zusätzlichen Job machen, oder? – ryzhman

0

Ihre session ist null - wird die session Bean erstellt werden oder ist die autowire einfach versagt es zu finden?

+0

Danke für eine Antwort. Wie kann ich es überprüfen? – ryzhman

+0

Laden Sie die Quellen für 'org.springframework.orm.hibernate4.LocalSessionFactoryBean' herunter und fügen Sie im Konstruktor einen Haltepunkt ein. – Lee

+0

Danke für einen Hinweis, aber Sessionfactory ist korrekt initialisiert. Das Problem liegt in der Verkabelung von Beans und dem Aufruf von Kontexten. – ryzhman

0

Sie nicht initialisiert Ihre Anwendungskontext

ApplicationContext context = new ClasspathApplicationContext("application-config.xml") 

oder mit Anmerkungen:

@Configuration 
@ImportXml("classpath:application-config.xml")