#java #spring #hibernate #jpa #entity
#java #spring #спящий режим #jpa #объект
Вопрос:
Я использую spring и спящий режим.
Моя сущность:
package com.igorgorbunov3333.core.entities.domain;
import com.igorgorbunov3333.core.entities.enums.Proceeding;
import javax.persistence.*;
import java.util.Date;
/**
* Created by Игорь on 03.04.2016.
*/
@Entity
@Table(name = "cases")
@NamedQueries({
@NamedQuery(name = "getAllCases", query = "SELECT c FROM Case c JOIN FETCH c.client JOIN FETCH c.firstInstance "
"JOIN FETCH c.secondInstance JOIN FETCH c.thirdInstance JOIN FETCH c.category")
})
public class Case {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "case_number")
private String caseNumber;
@ManyToOne
@JoinColumn(name = "client_id")
private Client client;
@OneToOne
@JoinColumn(name = "first_instance_id")
private FirstInstance firstInstance;
@OneToOne
@JoinColumn(name = "second_instance_id")
private SecondInstance secondInstance;
@OneToOne
@JoinColumn(name = "third_instance_id")
private ThirdInstance thirdInstance;
@Enumerated(EnumType.ORDINAL)
private Proceeding proceeding;
@Temporal(TemporalType.DATE)
@Column(name = "closing_date")
private Date closingDate;
@ManyToOne
@JoinColumn(name = "category_id")
private Category category;
private float price;
public long getId() {
return id;
}
public String getCaseNumber() {
return caseNumber;
}
public Client getClient() {
return client;
}
public FirstInstance getFirstInstance() {
return firstInstance;
}
public SecondInstance getSecondInstance() {
return secondInstance;
}
public ThirdInstance getThirdInstance() {
return thirdInstance;
}
public Proceeding getProceeding() {
return proceeding;
}
public Date getClosingDate() {
return closingDate;
}
public Category getCategory() {
return category;
}
public float getPrice() {
return price;
}
public void setId(long id) {
this.id = id;
}
public void setCaseNumber(String caseNumber) {
this.caseNumber = caseNumber;
}
public void setClient(Client client) {
this.client = client;
}
public void setFirstInstance(FirstInstance firstInstance) {
this.firstInstance = firstInstance;
}
public void setSecondInstance(SecondInstance secondInstance) {
this.secondInstance = secondInstance;
}
public void setThirdInstance(ThirdInstance thirdInstance) {
this.thirdInstance = thirdInstance;
}
public void setProceeding(Proceeding proceeding) {
this.proceeding = proceeding;
}
public void setClosingDate(Date closingDate) {
this.closingDate = closingDate;
}
public void setCategory(Category category) {
this.category = category;
}
public void setPrice(float price) {
this.price = price;
}
}
spring-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: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/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" >
<!--@Transaction annotation support -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--Scanning components in base-package (look for annotations) -->
<context:component-scan base-package="com.igorgorbunov3333"/>
<!--Activates various annotations to be detected in bean classes: Spring's @Required and @Autowired and so on-->
<context:annotation-config/>
<!--Обеспечивает работу с транзакциями в Spring -->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf"/>
</bean>
<!-- Datasource. Источник данных - база MySQL -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/database" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<!-- EntityManagerFactory -->
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--Поставщик данных - hibernate-->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<!--поиск сущностей в этом пакете-->
<property name="packagesToScan"
value="com.igorgorbunov3333"/>
<!--детали конфигурации поставщика постоянства (hibernate) -->
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQL5Dialect
</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
</beans>
Здесь я получаю исключение NullPointerException:
public Case findById(long id) {
return entityManager.find(Case.class, id);
}
Я уверен, что идентификатор правильный, но объект не может быть найден. Но когда я получаю все объекты, все в порядке:
public List<Case> findAll() {
Query query = entityManager.createNamedQuery("getAllCases");
return query.getResultList();
}
В чем причина?
Полный трек NPE:
09-Oct-2016 12:40:41.650 SEVERE [http-nio-8080-exec-7] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [ShowSingleCase] in context with path [] threw exception
java.lang.NullPointerException
at com.igorgorbunov3333.core.entities.service.impl.CaseServiceImpl.findById(CaseServiceImpl.java:32)
at com.igorgorbunov3333.web.servlet.display.single.ShowSingleCase.doGet(ShowSingleCase.java:29)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:522)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1096)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:760)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1480)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Мой CaseServiceImpl:
package com.igorgorbunov3333.core.entities.service.impl;
import com.igorgorbunov3333.core.entities.domain.Case;
import com.igorgorbunov3333.core.entities.enums.CaseStatus;
import com.igorgorbunov3333.core.entities.service.api.CaseService;
import com.igorgorbunov3333.core.util.DateUtil;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.*;
/**
* Created by Игорь on 27.07.2016.
*/
@Repository
@Service("CaseService")
public class CaseServiceImpl implements CaseService {
@PersistenceContext
private EntityManager entityManager;
public Case findById(long id) {
return entityManager.find(Case.class, id);
}
}
Сервлет:
package com.igorgorbunov3333.web.servlet.display.single;
import com.igorgorbunov3333.core.entities.domain.Case;
import com.igorgorbunov3333.core.entities.service.api.CaseService;
import com.igorgorbunov3333.core.entities.service.impl.CaseServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static com.igorgorbunov3333.web.util.Views.SINGLE_CASE_PAGE;
/**
* Created by Игорь on 09.08.2016.
*/
@WebServlet(name = "ShowSingleCase", urlPatterns = "/showSingleCase")
public class ShowSingleCase extends HttpServlet {
private CaseService caseService = new CaseServiceImpl();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
long id = Long.valueOf(request.getParameter("caseID"));
Case c = caseService.findById(id);
request.setAttribute("case", c);
request.getRequestDispatcher(SINGLE_CASE_PAGE).forward(request, response);
}
}
Комментарии:
1. У NPE есть трассировка стека. Итак, опубликуйте его
2. @Нил Стоктон, готово!
3. итак, как вы устанавливаете «EntityManager» в CaseServiceImpl?
4. @Нил Стоктон, мой вопрос обновлен!
5. Вы должны запросить у фреймворка экземпляр вашего класса CaseService, а не создавать его с
new
помощью . То, как вы это делаете, внедрение зависимостей entitymanager не выполняется, поэтому диспетчер объектов находитсяnull
в методе findById .
Ответ №1:
Ваша проблема в этой строке:
private CaseService caseService = new CaseServiceImpl();
Это не то, как работает внедрение зависимостей. Вы создаете экземпляр своего объекта CaseService вручную. В этом случае фреймворк не будет вводить никаких зависимостей, поэтому ваше private EntityManager entityManager;
поле будет null
. Вместо этого вы должны аннотировать свое caseService
поле @Autowired
аннотацией. Это подскажет Spring ввести компонент из контекста:
@Autowired
private CaseService caseService;
Ответ №2:
Единственное, что может быть null (не является примитивным) в указанной вами строке, что может вызвать проблему, — это EntityManager, поэтому вы ищете основную причину этого, которую я не вижу в опубликованном вами коде.
Комментарии:
1. Сбой find просто вернет null и не вызовет исключение, а примитивы не могут быть нулевыми. Кроме того, если параметр будет иметь значение null и это будет проблемой для find, исключение будет выдано из метода find .
Ответ №3:
Поскольку вы самостоятельно создаете объект класса CaseServiceImpl в своем классе сервлета, объект EntityManager не подключается автоматически spring, и именно по этой причине вы получаете исключение NullPointerException. либо вы должны автоматически подключить объект класса сервиса к классу сервлета, чтобы spring сам разрешил зависимость entitymanager и предоставил вам полностью настроенный объект service, либо вы должны установить объект entity manager в свой класс service при создании его объекта в servlet.