@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
  • Вопрос задан
  • 1916 просмотров
Пригласить эксперта
Ответы на вопрос 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)
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы