@KGirman

Could not commit JPA transaction. Как исправить?

Доброго времени суток. Не могу понять, почему возникает данная ошибка.
Кто знает, в чем причина, подскажите способ решения, пожалуйста!

Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the 
transaction] with root cause
javax.validation.ConstraintViolationException: Validation failed for classes [com.todo.todo.models.User] during persist time for groups [javax.validation.groups.Default, ]


User.java
package com.todo.todo.models;

import java.time.Instant;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.Setter;

@Entity
@Table(name = "usr")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Getter
    @Setter
    private Long id;

    @Getter
    @Setter
    @NotBlank(message = "Fill your name")
    private String name;

    @Getter
    @Setter
    @NotBlank(message = "Fill your login")
    private String login;

    @Getter
    @Setter
    @NotBlank(message = "Fill your password")
    private String password;

    @Getter
    @Setter
    private Instant createdDate;

    @Getter
    @Setter
    @OneToMany(cascade = CascadeType.ALL) // deleting a user causes deleting their tasks
    private List<Task> taskList;

    @Getter
    @Setter
    @ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
    @CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
    @Enumerated(EnumType.STRING)
    private Set<Role> roles;

    public User() {
    }
    public User(String name, String login, String password) {
        this.name = name;
        this.login = login;
        this.password = password;
        this.createdDate = Instant.now();
        this.taskList = new LinkedList<>();
        this.roles = new HashSet<>();
    }
}


UserRepository.java
package com.todo.todo.repositories;

import org.springframework.data.jpa.repository.JpaRepository;
import com.todo.todo.models.User;

public interface UserRepository extends JpaRepository<User, Long>{
    User findByLogin(String login);
}


UserController.java
Ошибка именно в строке userRepository.save(user);
package com.todo.todo.controllers;

import java.time.Instant;
import java.util.Collections;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.todo.todo.models.Role;
import com.todo.todo.models.User;
import com.todo.todo.repositories.UserRepository;

@Controller
public class UserController {

    @Autowired
    private UserRepository userRepository;
    
    @GetMapping("/registrate")
    public String getRegistratePage(){
        return "registrate";
    }

    @PostMapping("/registrate")
    public String registrateUser(User user, Map<String, Object> map){
        User userFromDatabase = userRepository.findByLogin(user.getLogin());
        if(userFromDatabase != null){
            map.put("error", "User has been already registrated!");
            return "registrate";
        }
        user.setCreatedDate(Instant.now());
        user.setRoles(Collections.singleton(Role.USER));
        userRepository.save(user); // Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
        return "redirect:/login";
    }
}


Текст ошибки (его часть)
Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction

Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [com.todo.todo.models.User] during persist time for groups [javax.validation.groups.Default, ]

631a602e24df2605210942.png
631a6034605e0393391220.png
  • Вопрос задан
  • 2500 просмотров
Пригласить эксперта
Ответы на вопрос 1
azerphoenix
@azerphoenix Куратор тега Java
Java Software Engineer
Доброго времени суток!
1)
ConstraintViolationException: Validation failed for classes

Судя по всему у вас есть некий constraint, который был нарушен и потому объект не был сохранен.
Попробуйте подебажить этот момент: Скорее всего проблема тут.
@Getter
    @Setter
    @ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
    @CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
    @Enumerated(EnumType.STRING)
    private Set<Role> roles;


Некоторые рекомендации не связанные с вопросом:
2) рекомендую ознакомитсья с паттерном DTO. Вам нужно принять DTO, замаппить его в Entity. Это более корректный способ.
3) нет смысла дублировать @Getter @Setter, если эти аннотации стоят над каждым полем. Попробуйте перенести его на уровен класса.
4)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы