Spring @Transactional причина NoClassDefFoundError - PullRequest
0 голосов
/ 30 ноября 2018

Парень попросил меня помочь ему устранить странную ошибку в службе безопасности его весеннего загрузочного приложения, после нескольких часов пути мне удалось исправить ошибку, но я действительно понятия не имею, что произойдет.Обратите внимание на следующие классы:

Класс 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<>();
}

Класс UserDto: реализация интерфейса Spring для управления учетными данными пользователя

@Getter
@Setter
@AllArgsConstructor
public class UserDto implements org.springframework.security.core.userdetails.UserDetails {
  private long id;
  private String Username;
  @JsonIgnore
  private String password;
  private Collection<? extends GrantedAuthority> authorities;

  public static UserDto create(User user) {
    List<GrantedAuthority> authorities = user.getRole().stream()
      .map(role -> new SimpleGrantedAuthority(role.getName().name())).collect(Collectors.toList());

    return new UserDto(user.getId(), user.getUserName(), user.getPassword(), authorities);
  }

  // implement interface's methods, only getters, not important
}

Class 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);
  }
}

Полный исходный код можно найти здесь (это всего лишь простое приложение с весенней загрузкой с некоторыми классами): https://github.com/raizo000/admin_project (его репозиторий использует встроенный tomcatЯ пытался изменить его на причал, но это не причина)

Когда я запускаю код первый раз с этими 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]
....

Я проверил файл JAR, в правом каталоге есть файл UserDto.class.

Удалите @Transactional, помогите исправить ошибку, но вызвайте еще одну ленивую ошибку инициализации, и я в итоге быстро заменю fetch = FetchType.LAZY в User классе на fetch = FetchType.EAGER.

Почему добавление Transactional может вызватьa NoClassDefFoundError?Является ли удаление Transactional правильным решением или есть лучшее решение?

1 Ответ

0 голосов
/ 30 ноября 2018

Когда класс не найден, первое, что вы должны сделать, это очистить и собрать.Потому что последняя сборка сохраняет некоторую зависимость.Таким образом, @ Transactional @interface не был найден в каком-либо поврежденном пакете.Перестройка (чистая сборка) решает ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...