Java Spring@Transactional cause NoClassDefFoundError
一个家伙请求我帮助他解决spring boot应用程序安全服务中的一个奇怪的错误,经过几个小时的追踪,我设法修复了这个错误,但我真的不知道发生了什么。请看这些课程: ClassJava Spring@Transactional cause NoClassDefFoundError,java,spring-boot,spring-transactions,Java,Spring Boot,Spring Transactions,一个家伙请求我帮助他解决spring boot应用程序安全服务中的一个奇怪的错误,经过几个小时的追踪,我设法修复了这个错误,但我真的不知道发生了什么。请看这些课程: ClassUser:数据库中的用户信息 @Getter @Setter @Entity @Table(name = "user", uniqueConstraints = {@UniqueConstraint(columnNames = {"user_name"})}) public class User extends DateA
User
:数据库中的用户信息
@Getter
@Setter
@Entity
@Table(name = "user", uniqueConstraints = {@UniqueConstraint(columnNames = {"user_name"})})
public class User extends DateAudit implements Serializable {
// Id, username, password and constructor... not really important
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> role = new HashSet<>();
}
类CustomUserService
:身份验证服务
@Service
public class CustomUserService implements org.springframework.security.core.userdetails.UserDetailsService {
private final UserRepository userRepository;
@Autowired
public CustomUserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
@Transactional
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
User user = userRepository.findUserByUserName(userName).orElseThrow(() -> {
return null;
});
return UserDto.create(user);
}
}
完整的源代码可以在这里找到(它只是一个带有一些类的简单spring boot应用程序):(他的repo使用嵌入式tomcat,我已经尝试将其更改为jetty,但这不是原因)
当我第一次使用这3个类运行代码时。线路
return UserDto.create(user);
给我一个NoClassDefFoundError
:
WARN 7252 --- [qtp223566397-22] org.eclipse.jetty.server.HttpChannel : /login
java.lang.NoClassDefFoundError: com/example/admin/dto/UserDto
at com.example.admin.services.CustomUserService.loadUserByUsername(CustomUserService.java:28) ~[classes/:na]
at com.example.admin.services.CustomUserService$$FastClassBySpringCGLIB$$b9234a59.invoke(<generated>) ~[classes/:na]
....
WARN 7252---[qtp223566397-22]org.eclipse.jetty.server.HttpChannel:/login
java.lang.NoClassDefFoundError:com/example/admin/dto/UserDto
在com.example.admin.services.CustomUserService.loadUserByUsername(CustomUserService.java:28)~[classes/:na]
在com.example.admin.services.CustomUserService$$FastClassBySpringCGLIB$$b9234a59.invoke()~[classes/:na]
....
我已经检查了jar文件,在正确的目录中有一个UserDto.class文件
删除@Transactional
帮助修复错误,但导致另一个延迟初始化错误,我最终将User
类中的fetch=FetchType.LAZY
更改为fetch=FetchType.EAGER
作为快速修复
为什么添加事务会导致NoClassDefFoundError?“删除事务性”是正确的解决方案,还是有更好的解决方案?当找不到类时,首先应该进行清理和生成。 因为,上一次构建保存了一些依赖关系。 因此在某个损坏的包中找不到@接口。
重新生成(干净的构建)可以解决这个问题。请您将@Transactional放在类标题中,让我们知道发生了什么?我现在非常困惑,在代码工作之后,您提到的在方法级别或类级别再添加@Transactional都不会导致错误。我尝试
mvn clean
然后重新启动应用程序,但我不能让错误再次发生!是的,所以包装清洁问题解决了。在@Transactional interface上找不到依赖项。我仍然不明白。请在你的回答中解释清楚。done@HaiHoang。也许这是maven的一个罕见/奇怪的问题。因为每次构建我都会运行mvn clean install
。似乎是我第一次删除@Transactional修复包,然后错误就再也不会发生了。
WARN 7252 --- [qtp223566397-22] org.eclipse.jetty.server.HttpChannel : /login
java.lang.NoClassDefFoundError: com/example/admin/dto/UserDto
at com.example.admin.services.CustomUserService.loadUserByUsername(CustomUserService.java:28) ~[classes/:na]
at com.example.admin.services.CustomUserService$$FastClassBySpringCGLIB$$b9234a59.invoke(<generated>) ~[classes/:na]
....