java - Spring CGlib 自动运行的奇怪行为?

标签 java spring spring-mvc autowired cglib

我正在使用 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 的片段:

enter image description here

但是EventRepository不是:

enter image description here

两者的配置相同。第一个存储库自动连接正常,第二个存储库失败。我刚到 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/

相关文章:

java - 如何添加glassfish工具来 eclipse 氧3a

java - Spring Security - 终端双重身份验证 : X. 509,用户登录表单

java - 使用 Resteasy/Hibernate/Spring 简化 DAO 层

javax.servlet.ServletException : Could not resolve view with name 'home' in servlet with name 'dispatcher'

java - servlet 连接中的 Http 503 错误

java - 为什么这段代码会抛出 IOException?

java - 使用速度模板格式化电子邮件正文?

java - Spring Boot如何将ArrayList转换为Pageable对象

Spring MVC : Common param in all requests

java - 这些元素叫什么?