我正在使用 Spring MVC
应用程序。
我想创建新事件:
fill data at page > controller handle this info > saving new event to DB
我已经创建了 DAO 层和存储库层。但在某些地方,它的行为非常奇怪。我以相同的方式为所有存储库创建了 Java 配置。
这是存储库配置代码片段:
@Configuration
@ComponentScan({ "net.lelyak.edu.repository", "net.lelyak.edu.service" })
@Import({ DatabaseDAOConfiguration.class })
public class ApplicationConfiguration {
@Autowired
private UserDAO userDAO;
@Autowired
private EventDAO eventDAO;
@Autowired
private TicketDAO ticketDAO;
@Autowired
private AuditoriumDAO auditoriumDAO;
@Bean
public AuditoriumRepository auditoriumRepository() {
AuditoriumRepository auditoriumRepository = new AuditoriumRepository();
auditoriumRepository.setDao(auditoriumDAO);
return auditoriumRepository;
}
@Bean
public EventRepository eventRepository() {
EventRepository eventRepository = new EventRepository();
eventRepository.setDao(eventDAO);
return eventRepository;
}
我在 Controller 级别遇到了奇怪的行为。
这是 Controller 代码片段:
@Controller
@RequestMapping("events")
public class EventsController {
@Autowired
private AuditoriumRepository auditoriumRepository;
@Autowired
private EventRepository eventRepository;
@RequestMapping(path = "add", method = RequestMethod.POST)
public String addEvent(@RequestParam Map<String, String> allRequestParams) {
Event newEvent = new Event();
// get auditorium id from request
String auditoryIdString = allRequestParams.get("auditorium");
Long auditoryId = Long.parseLong(auditoryIdString);
Auditorium auditorium = auditoriumRepository.getById(auditoryId);
newEvent.setAuditorium(auditorium);
AuditoriumRepository 可以自动连接。
这是调试 View 的片段:
但是EventRepository不是:
两者的配置相同。第一个存储库自动连接正常,第二个存储库失败。我刚到 Spring 。我不明白为什么会发生这种情况?
以下是来自 EventRepository 的代码片段:
public class EventRepository extends BaseRepository<Event, EventDAO> {
@Autowired
private AuditoriumRepository auditoriumRepository;
@Override
public int put(Event entity) {
auditoriumRepository.put(entity.getAuditorium());
return super.put(entity);
}
AuditoriumRepository代码片段:
public class AuditoriumRepository extends BaseRepository<Auditorium, AuditoriumDAO> {
@Override
public Auditorium preSave(Auditorium entity) {
return entity;
}
为了将新事件保存到数据库,我必须使用EventRepository。当然,它失败了,并显示以下堆栈跟踪:
java.lang.NullPointerException
at net.lelyak.edu.repository.BaseRepository.put(BaseRepository.java:23)
at net.lelyak.edu.repository.EventRepository.put(EventRepository.java:20)
at net.lelyak.edu.repository.EventRepository$$FastClassBySpringCGLIB$$5de8d2a5.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
我在 Windows 10 上使用 spring 4.2.4.RELEASE
。
更新:
BaseRepository代码片段:
public abstract class BaseRepository<T extends BaseEntity, E extends BaseDAO<T>> {
private E dao;
public E getDao() {
return dao;
}
public void setDao(E dao) {
this.dao = dao;
}
public int put(T entity) {
return dao.save(preSave(entity));
}
我不明白为什么要使用相同的配置和存储库结构。一个实例由 Spring 正常自动连接,但第二个实例失败。如何找到这个问题的根源呢?和一些解决方案。
更新2:
我已经尝试了推荐的解决方案,并将下一个 setter 添加到EventRepository:
public void setAuditoriumRepository(AuditoriumRepository auditoriumRepository) {
System.out.println("EventRepository.setAuditoriumRepository");
this.auditoriumRepository = auditoriumRepository;
}
日志消息显示此 setter 已执行。但由于同样的原因不断失败。
如何解决这个问题?
最佳答案
我看到了你的代码,问题与 Spring 和 Autowiring 过程无关。问题出在 BaseDAO 类中的 save
方法中:
@Override
public Integer save(ENTITY entity) {
if (entity.getId() == null) {
insert(entity);
} else {
update(entity);
}
return null;
}
如果您更改方法以返回新插入/更新的实体 ID,它将正常工作。
尝试对其进行硬编码以进行测试:
@Override
public Integer save(ENTITY entity) {
if (entity.getId() == null) {
insert(entity);
} else {
update(entity);
}
return 1;
}
当您从 save
方法返回 null
时,就会出现问题,然后您正在 EventsController
类中进行分配,即:
int eventId = eventRepository.put(newEvent);//this 为 null
并抛出 NullPointerException
,因为您试图将 null
分配给原始变量。
关于java - Spring CGlib 自动运行的奇怪行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36166614/