org.postgresql.util.PSQLException: ОШИБКА: столбец нельзя автоматически привести к типу
Делаю CRUD приложение на Spring Boot, подключены зависимость Spring Web и PostgreSQL. В ней была такая таблица:
create table dogs (id int not null generated by default as identity primary key, nickname varchar(20) not null, name varchar(40), breed varchar(30), date_of_birth timestamp without time zone, puppies_count int);
Добавил в нее несколько записей, в т.ч. в колонку breed
. Затем решил изменить тип этой колонки на enum
:
очистил колонку, создал перечисление и изменил тип столбца с текстового на это перечисление:
update dogs set breed = null;
create type breed as enum ('WHWT', 'SCOTTISH_T', 'SEALYHAM_T', 'JRT', 'AUSTRALIAN_S', 'METIS', 'OTHER');
alter table dogs alter column breed set data type breed using breed::breed;
После этого Eclipse стал выдавать такую ошибку:
Caused by: org.postgresql.util.PSQLException: ОШИБКА: столбец "breed" нельзя автоматически привести к типу smallint
Подсказка: Возможно, необходимо указать "USING breed::smallint".
Пробовал делать как в подсказке - не работает. И откуда попытка привести это к smallint?
Сущность:
package com.example.demo6.entities;
import java.time.LocalDateTime;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
@Entity
@Table(name = "dogs")
public class Dog {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank(message = "Nickname should not be empty")
@Size(min = 3, max = 30, message = "Nickname should be between 3 and 30 characters long")
private String nickname;
@Size(min = 3, max = 30, message = "Name should be between 3 and 30 characters long")
private String name;
private Breed breed;
@Column(name = "date_of_birth")
private LocalDateTime dateOfBirth;
@Column(name = "puppies_count")
private int puppies;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Breed getBreed() {
return breed;
}
public void setBreed(Breed breed) {
this.breed = breed;
}
public LocalDateTime getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(LocalDateTime dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public int getPuppies() {
return puppies;
}
public void setPuppies(int puppies) {
this.puppies = puppies;
}
public Dog() {}
public enum Breed {
WHWT("Вест Хайленд Вайт Терьер"),
SCOTTISH_T("Скотч Терьер"),
SEALYHAM_T("Силихем Терьер"),
JRT("Джек Рассел Терьер"),
AUSTRALIAN_S("Австралийская овчарка"),
METIS("Метис/Дворняга"),
OTHER("Другая");
Breed(String breed){}
}
}
Контроллер:
package com.example.demo6.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.demo6.entities.Dog;
import com.example.demo6.service.DogService;
@Controller
@RequestMapping("/")
public class DogController {
private DogService dogService;
@Autowired
public DogController(DogService dogService) {
this.dogService = dogService;
}
public DogService getDogService() {
return dogService;
}
public void setDogService(DogService dogService) {
this.dogService = dogService;
}
@GetMapping("")
public String index(Model model) {
model.addAttribute("dog", new Dog());
model.addAttribute("dogs", dogService.findAll());
return "index";
}
@PostMapping("")
public String add(@ModelAttribute("dog") Dog dog, Model model) {
dogService.save(dog);
return "redirect:/";
}
}
Главная страница:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Собаки</title>
<style>
table {
width: 100%;
border: 4px double black;
border-collapse: collapse;
}
th {
text-align: left;
background: #ccc;
padding: 5px;
border: 1px solid black;
}
td {
padding: 5px;
border: 1px solid black;
}
</style>
</head>
<body>
<div th:if="${isUserAuth}">Выйти</div>
<div th:unless="${isUserAuth}">Войти</div>
<div sec:authorize="isAuthenticated()">
<p>user@ukr.net</p> <a href="/logout">Logout</a>
</div>
<div sec:authorize="!isAuthenticated()">
<p>Hello, guest! Please <a href="/login">Login</a> or <a href="/signup">SignUp</a></p>
</div>
<table border="1" color="black" border-collapse="collapse">
<tr>
<td><b>ID</b></td>
<td><b>Кличка</b></td>
<td><b>Имя</b></td>
<td><b>Порода</b></td>
<td><b>Дата рождения</b></td>
<td><b>Щенки</b></td>
</tr>
<tr>
<form modelAttribute="dog" th:method="POST" th:object:"${dog}" th:action="@{/}" action="#">
<td><input type="submit" value="Добавить"/></td>
<td><input type="text" th:field="*{dog.nickname}" id="dog.nickname"/></td>
<td><input type="text" th:field="*{dog.name}" id="dog.name"/></td>
<td><input type="text" th:field="*{dog.breed}" id="dog.breed"/></td>
<td><input type="text" th:field="*{dog.dateOfBirth}" id="dog.dateOfBirth"/></td>
<td><input type="text" th:field="*{dog.puppies}" id="dog.puppies"/></td>
</form>
</tr>
<tr th:each="dog : ${dogs}">
<td th:text="${dog.id}">1</td>
<td th:text="${dog.nickname}"></td>
<td th:text="${dog.name}"></td>
<td th:text="${dog.breed}"></td>
<td th:text="${dog.dateOfBirth}"></td>
<td th:text="${dog.puppies}"></td>
<br>
</tr>
</table>
</body>
</html>
Еще только что заметил, что Hibernate при старте приложения почему-то сам добавляет эту колонку
Hibernate: alter table if exists dogs add column breed smallint check (breed between 0 and 6)