我正在使用MySQL作为数据库的Spring JPA应用程序。我确保所有spring-jpa库,hibernate和mysql-connector-java都已加载。
我正在运行一个mysql 5实例。以下是我的application.properties文件的摘录:
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.datasource.url=jdbc:mysql://localhost/mydatabase
spring.datasource.username=myuser
spring.datasource.password=SUPERSECRET
spring.datasource.driverClassName=com.mysql.jdbc.Driver
执行集成测试时,spring正常启动但在创建hibernate SessionFactory时失败,但有例外:
org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111
我认为我的方言应该是Mysql5Dialect,我也尝试过明确说明InnoDB的方言,以及两个方言选项,它们并不表示版本5.但是我总是得到相同的'没有方言的JDBC类型映射: 1111'消息。 我的application.properties文件驻留在test / resources源文件夹中。它被JUnit Test跑者认可(我以前因为打字错误而得到例外)。
属性我设置错了吗?我找不到关于这些属性名称的一些官方文档,但在这个stackoverflow答案中找到了一个提示:https://stackoverflow.com/a/25941616/1735497
期待您的回答,谢谢!
BTW该应用程序已使用弹簧启动。
答案 0 :(得分:13)
这里的答案基于SubOptimal的评论:
错误消息实际上表示一个列类型无法通过hibernate映射到数据库类型。
在我的例子中,它是我在某些实体中用作主键的java.util.UUID
类型。只需应用注释@Type(type="uuid-char")
(适用于postgres @Type(type="pg-uuid")
)
答案 1 :(得分:8)
还有另一个常见的用例抛出此异常。调用返回void
的函数。有关更多信息和解决方案,请转到here。
答案 2 :(得分:5)
我遇到了同样的错误,因为我的查询返回了UUID列。为了解决此问题,我通过“ cast(columnName as varchar)”之类的查询将UUID列作为varchar类型返回,然后它起作用了。
示例:
public interface StudRepository extends JpaRepository<Mark, UUID> {
@Modifying
@Query(value = "SELECT Cast(stuid as varchar) id, SUM(marks) as marks FROM studs where group by stuid", nativeQuery = true)
List<Student> findMarkGroupByStuid();
public static interface Student(){
private String getId();
private String getMarks();
}
}
答案 3 :(得分:5)
我遇到了同样的错误,这里的问题是存储在数据库中的UUID没有转换为对象。
我尝试应用这些注释@Type(type =“ uuid-char”)(对于postgres @Type(type =“ pg-uuid”)),但对我而言不起作用。
这对我有用。假设您要使用JPA中的本机查询从表中获取ID和名称。使用字段ID和名称创建一个实体类(例如“用户”),然后尝试将object []转换为所需的实体。这里匹配的数据是我们从查询中获得的对象数组的列表。
@Query( value = "SELECT CAST(id as varchar) id, name from users ", nativeQuery = true)
public List<Object[]> search();
public class User{
private UUID id;
private String name;
}
List<User> userList=new ArrayList<>();
for(Object[] data:matchedData){
userList.add(new User(UUID.fromString(String.valueOf(data[0])),
String.valueOf(data[1])));
}
假设这是我们拥有的实体
答案 4 :(得分:5)
首先,您没有提供实体映射,所以我们可以知道是什么列导致了此问题。例如,它可以是UUID
或JSON
列。
现在,您正在使用非常古老的休眠方言。 MySQL5Dialect
适用于MySQL5。很可能您正在使用更新的MySQL版本。
因此,请尝试改用MySQL8Dialect
:
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
如果由于使用JSON列类型而遇到问题,请尝试提供支持非标准Type的自定义Hibernate方言:
public class MySQL8JsonDialect
extends MySQL8Dialect{
public MySQL8JsonDialect() {
super();
this.registerHibernateType(
Types.OTHER, JsonStringType.class.getName()
);
}
}
可以使用自定义的“休眠方言”:
<property
name="hibernate.dialect"
value="com.vladmihalcea.book.hpjp.hibernate.type.json.MySQL8JsonDialect"
/>
如果在执行SQL本机查询时遇到此异常,则需要通过addScalar
传递类型:
JsonNode properties = (JsonNode) entityManager
.createNativeQuery(
"SELECT properties " +
"FROM book " +
"WHERE isbn = :isbn")
.setParameter("isbn", "978-9730228236")
.unwrap(org.hibernate.query.NativeQuery.class)
.addScalar("properties", JsonStringType.INSTANCE)
.getSingleResult();
assertEquals(
"High-Performance Java Persistence",
properties.get("title").asText()
);
有关此主题的更多详细信息,请同时查看this article。
答案 5 :(得分:3)
有时当你调用sql过程/函数时,可能需要返回一些东西。您可以尝试返回void:RETURN;
或字符串(这个对我有用):RETURN 'OK'
答案 6 :(得分:0)
就我而言,它是通过添加 columnDefinition 解决的:
@Column(columnDefinition = "json")
答案 7 :(得分:0)
如果使用 Postgres
public class CustomPostgreSqlDialect extends PostgreSQL94Dialect{
@Override
public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor)
{
switch (sqlTypeDescriptor.getSqlType())
{
case Types.CLOB:
return VarcharTypeDescriptor.INSTANCE;
case Types.BLOB:
return VarcharTypeDescriptor.INSTANCE;
case 1111://1111 should be json of pgsql
return VarcharTypeDescriptor.INSTANCE;
}
return super.remapSqlTypeDescriptor(sqlTypeDescriptor);
}
public CustomPostgreSqlDialect() {
super();
registerHibernateType(1111, "string");
}}
并使用
<prop key="hibernate.dialect">com.abc.CustomPostgreSqlDialect</prop>
答案 8 :(得分:0)
就我而言,问题是 Hibernate 不知道如何处理 UUID
列。如果您使用 Postgres,请尝试将其添加到您的 resources/application.properties
:
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
答案 9 :(得分:0)
另一个简单的解释可能是您正在获取一个复杂的类型(实体/POJO)但没有指定要映射到的实体:
String sql = "select yourentity.* from {h-schema}Yourentity yourentity";
return entityManager.createNativeQuery(sql).getResultList();
只需在 createNativeQuery 方法中添加要映射到的类:
return entityManager.createNativeQuery(sql, Yourentity.class).getResultList();
答案 10 :(得分:0)
返回 void 的函数或过程会导致JPA / Hibernate出现问题,因此使用return integer 对其进行更改并在过程末尾调用return 1可能会解决此问题。
SQL类型1111表示字符串。
答案 11 :(得分:0)
这是针对Hibernate(5.x)版本的
调用返回JSON字符串/对象的数据库函数
为此,请使用unwrap(org.hibernate.query.NativeQuery.class).addScalar()
方法。
以下示例(春季和冬眠):
@PersistenceContext
EntityManager em;
@Override
public String getJson(String strLayerName) {
String *nativeQuery* = "select fn_layer_attributes(:layername)";
return em.createNativeQuery(*nativeQuery*).setParameter("layername", strLayerName).**unwrap(org.hibernate.query.NativeQuery.class).addScalar**("fn_layer_attributes", **new JsonNodeBinaryType()**) .getSingleResult().toString();
}
答案 12 :(得分:0)
如果您有本机SQL查询,则可以通过在查询中添加强制转换来解决它。
示例:
CAST('yourString' AS varchar(50)) as anyColumnName
对于我来说,它对我有用。
答案 13 :(得分:0)
如果您使用的是Postgres,请检查您是否没有 Abstime 类型的列。 Abstime是JPA无法识别的内部Postgres数据类型。在这种情况下,如果您的业务需求允许,使用 TO_CHAR 可以转换为文本。
答案 14 :(得分:0)
当您使用Hibernate并返回void函数时,也会发生这种情况。至少有postgres。它不知道如何处理空白。我最终不得不将我的void更改为return int。
答案 15 :(得分:0)
就我而言,问题在于,当我在User类中设置存储过程时,我忘了添加resultClasses属性。
@NamedStoredProcedureQuery(name = "find_email",
procedureName = "find_email", resultClasses = User.class, //<--I forgot that.
parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "param_email", type = String.class)
}),
答案 16 :(得分:0)
对于任何使用旧的hibernate(3.x)版本获取此错误的人:
不要用大写字母写回程类型。 hibernate类型实现映射使用小写返回类型并且不转换它们:
CREATE OR REPLACE FUNCTION do_something(param varchar)
RETURNS integer AS
$BODY$
...