java - 如何使用 Hibernate 持久化枚举类型字段?
问题描述
我有以下代码
回购
package my.taco.data;
import my.taco.models.Ingredient;
import org.springframework.data.repository.CrudRepository;
public interface IngredientRepository extends CrudRepository <Ingredient,String> {
}
控制器
package my.taco.web;
import my.taco.data.IngredientRepository;
import my.taco.data.TacoRepository;
import my.taco.models.Ingredient;
import my.taco.models.Ingredient.Type;
import my.taco.models.Order;
import my.taco.models.Taco;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Controller
@RequestMapping("/design")
@SessionAttributes("order")
public class DesignTacoController {
private final IngredientRepository ingredientRepo;
private TacoRepository designRepo;
@Autowired
public DesignTacoController(IngredientRepository ingredientRepo,TacoRepository designRepo){
this.ingredientRepo=ingredientRepo;
this.designRepo=designRepo;
}
@ModelAttribute(name="order")
public Order order(){
return new Order();
}
@ModelAttribute(name = "design")
public Taco taco(){
return new Taco();
}
@GetMapping
public String showDesignForm(Model model){
List<Ingredient> ingredients= new ArrayList<>();
ingredientRepo.findAll().forEach(i->ingredients.add(i));
Type[] types=Ingredient.Type.values();
for(Type type: types){
model.addAttribute(type.toString().toLowerCase(),filterByType(ingredients,type));
}
return "design";
}
@PostMapping
public String processDesign(@Valid Taco design, Errors errors,@ModelAttribute Order order){
if(errors.hasErrors()){
return "design";
}
Taco saved=designRepo.save(design);
order.addDesign(saved);
return "redirect:/orders/current";
}
private List<Ingredient> filterByType(List<Ingredient> ingredients, Type type){
return ingredients.stream()
.filter(x->x.getType().equals(type))
.collect(Collectors.toList());
}
}
领域
package my.taco.models;
import lombok.*;
import javax.persistence.Entity;
import javax.persistence.Id;
@Data
@RequiredArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE,force = true)
@Entity
public class Ingredient {
@Id
private final String id;
private final String name;
private final Type type;
public enum Type{
WRAP,PROTEIN,VEGGIES,CHEESE,SAUCE
}
}
看法
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org" lang="pl">
<head>
<meta charset="utf-8">
<title>Aplikacja Taco Cloud</title>
<link rel="stylesheet" th:href="@{/styles.css}"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<h1>Przygotuj własne taco</h1>
<img th:src="@{/images/TacoCloud.png}" class="img-thumbnail">
<form method="POST" th:object="${design}">
<div class="grid">
<div class="ingredient-group" id="wraps">
<h3>Wybierz rodzaj mąki:</h3>
<div th:each="ingredient: ${wrap}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
<span th:text="${ingredient.name}">SKŁADNIK</span>
</div>
</div>
<div class="ingredient-group" id="proteins">
<h3>Wybierz mięso:</h3>
<div th:each="ingredient : ${protein}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
<span th:text="${ingredient.name}">SKŁADNIK</span>
</div>
</div>
<div class="ingredient-group" id="cheeses">
<h3>Wybierz sery:</h3>
<div th:each="ingredient: ${cheese}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
<span th:text="${ingredient.name}">SKŁADNIK</span>
</div>
</div>
<div class="ingredient-group" id="veggies">
<h3>Wybierz warzywa</h3>
<div th:each="ingredient: ${veggies}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
<span th:text="${ingredient.name}">SKŁADNIK</span>
</div>
<div class="ingredient-group" id="sauces">
<h3>Wybierz sosy</h3>
<div th:each="ingredient: ${sauce}">
<input type="checkbox" th:value="${ingredient.id}"/>
<span th:text="${ingredient.name}">SKŁADNIK</span>
</div>
</div>
</div>
<h3>Nadaj nazwę przygotowanemu taco:</h3>
<button>Wyślij swoje zamówienie</button>
</div>
</form>
</div>
</body>
</html>
当我去 /design 我有以下错误
Whitelabel Error Page This application has no explicit mapping for
/error, so you are seeing this as a fallback.
Sun Mar 14 00:28:34 CET 2021 There was an unexpected error
(type=Internal Server Error, status=500). could not execute query; SQL
[select ingredient0_.id as id1_0_, ingredient0_.name as name2_0_,
ingredient0_.type as type3_0_ from ingredient ingredient0_]; nested
exception is org.hibernate.exception.DataException: could not execute
query org.springframework.dao.DataIntegrityViolationException: could
not execute query; SQL [select ingredient0_.id as id1_0_,
ingredient0_.name as name2_0_, ingredient0_.type as type3_0_ from
ingredient ingredient0_]; nested exception is
org.hibernate.exception.DataException: could not execute query
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:280)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at com.sun.proxy.$Proxy96.findAll(Unknown Source)
at my.taco.web.DesignTacoController.showDesignForm(DesignTacoController.java:49)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:887)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1684)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by:
org.hibernate.exception.DataException: could not execute query
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:52)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.loader.Loader.doList(Loader.java:2852)
at org.hibernate.loader.Loader.doList(Loader.java:2831) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2663) at org.hibernate.loader.Loader.list(Loader.java:2658) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:506) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1414)
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1625)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1593)
at org.hibernate.query.Query.getResultList(Query.java:165)
at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:76)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:356)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:524)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:531)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:156)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:131)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
... 58 more
Caused by: org.h2.jdbc.JdbcSQLDataException: Błądkonwersji danych "WRAP" Data conversion error converting "WRAP" [22018-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:457)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
at org.h2.message.DbException.get(DbException.java:194)
at org.h2.value.Value.convertTo(Value.java:875) at org.h2.value.Value.convertTo(Value.java:737) at org.h2.value.Value.getInt(Value.java:623) at org.h2.jdbc.JdbcResultSet.getInt(JdbcResultSet.java:352) at com.zaxxer.hikari.pool.HikariProxyResultSet.getInt(HikariProxyResultSet.java)
at org.hibernate.type.descriptor.sql.IntegerTypeDescriptor$2.doExtract(IntegerTypeDescriptor.java:62)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
at org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter.readValue(OrdinalEnumValueConverter.java:66)
at org.hibernate.type.EnumType.nullSafeGet(EnumType.java:250)
at org.hibernate.type.CustomType.nullSafeGet(CustomType.java:119) at org.hibernate.type.AbstractType.hydrate(AbstractType.java:91) at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:3135)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1869)
at org.hibernate.loader.Loader.hydrateEntityState(Loader.java:1797)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1770)
at org.hibernate.loader.Loader.getRow(Loader.java:1622) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:740) at org.hibernate.loader.Loader.getRowsFromResultSet(Loader.java:1039) at org.hibernate.loader.Loader.processResultSet(Loader.java:990) at org.hibernate.loader.Loader.doQuery(Loader.java:959) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349)
at org.hibernate.loader.Loader.doList(Loader.java:2849) ... 89 more
Caused by: java.lang.NumberFormatException: For input string: "WRAP"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Integer.parseInt(Integer.java:652) at java.base/java.lang.Integer.parseInt(Integer.java:770) at org.h2.value.Value.convertToInt(Value.java:982) at org.h2.value.Value.convertTo(Value.java:806) ... 110 more
我知道怎么了
架构.sql
create table if not exists Ingredient (id varchar(4) not null,
name varchar(40) not null, type varchar(10) not null);
数据.sql
> delete from Taco_Order_Tacos; delete from Taco_Ingredients; delete
> from Taco; delete from Taco_Order;
>
> delete from Ingredient;
>
> insert into Ingredient (id, name, type)
> values ('FLTO', 'Flour Tortilla', 'WRAP'); insert into Ingredient (id, name, type)
> values ('COTO', 'Corn Tortilla', 'WRAP'); insert into Ingredient (id, name, type)
> values ('GRBF', 'Ground Beef', 'PROTEIN'); insert into Ingredient (id, name, type)
> values ('CARN', 'Carnitas', 'PROTEIN'); insert into Ingredient (id, name, type)
> values ('TMTO', 'Diced Tomatoes', 'VEGGIES'); insert into Ingredient (id, name, type)
> values ('LETC', 'Lettuce', 'VEGGIES'); insert into Ingredient (id, name, type)
> values ('CHED', 'Cheddar', 'CHEESE'); insert into Ingredient (id, name, type)
> values ('JACK', 'Monterrey Jack', 'CHEESE'); insert into Ingredient (id, name, type)
> values ('SLSA', 'Salsa', 'SAUCE'); insert into Ingredient (id, name, type)
> values ('SRCR', 'Sour Cream', 'SAUCE');
添加了数据和架构以获取有关问题的更多详细信息。类型是 varchar 类型所以 idk 为什么我有数字异常我的表中没有任何数字
解决方案
您应该添加@Enumerated(EnumType.STRING)
您的type
字段,例如:
@Enumerated(EnumType.STRING)
private final Type type;
这将允许在相应的 varchar 列中将 Enum 字段作为字符串持久化。
Ingredient
表的type
列是 varchar 类型,enum
需要表示为字符串,以便映射到该列。
推荐阅读
- android - RazorPay Android:使用 callback_url 时卡在 RazorPay 视图中
- css - 如何为 Blazorise 卡片图像添加圆角?
- shortcut - () 的崇高快捷方式
- reactjs - 如何在 React 中显示我的数组的单击元素?
- nuxt.js - 在 nuxt.js 中重写 url
- google-apps-script - 从谷歌表格复制列的所有值并将它们添加为电子表格中的编辑器时显示错误
- django - 将私有子网中的 Django-NGINX 内容提供给 AWS 应用程序负载均衡器
- python - 当日期如下所示时如何在熊猫中按日期分组:2017-06-16 09:34:23?
- python - 同底数
- xml - 如何使用 XSLT 1.0 将 XML 复杂类型元素转换为 XML 转换的单个元素