Spring / hibernate - обработка дубликатов - PullRequest
0 голосов
/ 04 октября 2018

У меня проблема с обработкой дублирующейся записи в БД.Я перебрал Google и Stack и не нашел рабочего решения.

Вот мой код:

DB:

 DROP TABLE IF EXISTS `batch`;
    CREATE TABLE `batch` (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `batch_number` int(3) NOT NULL,
        `batch_style` varchar(45) DEFAULT NULL,
        `batch_name` varchar(45) DEFAULT NULL,
        `batch_creation_date` DATE,
        PRIMARY KEY (`id`),
        UNIQUE KEY(`batch_number`)
    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;    

    LOCK TABLE `batch` WRITE;

POJO:

@Entity
@Table(name="batch")
public class Batch {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private int id;

    @Column(name="batch_number")
    private Integer batchNumber;

    @Column(name="batch_style")
    private String batchStyle;

    @Column(name="batch_name")
    private String batchName;

    @Column(name="batch_creation_date")
    private LocalDate  batchCreationDate;

    Setters / Getters / Constructors / toString...

Контроллер (часть):

    @Controller
    @RequestMapping("/batch")
    public class BatchController {

        @Autowired
        private BatchService batchService;

        @Autowired
        private MaltService maltService;

        @PostMapping("/saveBatch")
        public String saveBatch(@Valid @ModelAttribute("batch") Batch theBatch, BindingResult theBindingResult) {

            if (theBindingResult.hasErrors()) {
                return "batch-form";
            }
            else {
                try {
                    batchService.saveBatch(theBatch);

                    return "redirect:/batch/list";

                } catch (ConstraintViolationException e) {
                    theBindingResult.rejectValue("batchNumber", "duplicate", "Invalid number");
                    return "batch-form";
                }
            }
        }       

@GetMapping("/showBatchUpdateForm")
    public String showBatchUpdateForm(@RequestParam("batchId") int theId, Model theModel) {

        // get batch form our service
        Batch theBatch = batchService.getBatch(theId);

        // set  as a model to prepopulate the form
        theModel.addAttribute("batch", theBatch);

        return "batch-form";
    }
}

Далее у меня DAO и Service.DaoImpl (часть этого):

@Repository
public class BatchDAOImpl implements BatchDAO {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public void saveBatch(Batch theBatch) {

        Session currentSession = sessionFactory.getCurrentSession();

        currentSession.saveOrUpdate(theBatch);
    }    
}

Проблема: Когда я редактирую запись (т.е. batchNumber = 2) и просто сохраняю ее, оставляя исходный номер - все в порядке, никаких исключений не выдается.Когда я пытаюсь изменить batchNumber=2 на batchNumber=1 (уже занятый номер), я получаю исключение:

java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'batch_number_UNIQUE'

Я хотел бы добавить, когда я использую тот же подход для предотвращения дублирования в другомсущность, это работает, поэтому после часов отладки я понятия не имею, что здесь происходит.Я могу опубликовать весь код на github.

Есть предложения?

1 Ответ

0 голосов
/ 05 октября 2018

Вы ловите неправильное исключение.В вашем контроллере вы ловите org.hibernate.exception.ConstraintViolationException, но операция сохранения выдает java.sql.SQLIntegrityConstraintViolationException.В общем, вам просто нужно изменить пойманное исключение в контроллере.

...