Jpa Join 查询与来自两个表的数据,org.hibernate.MappingException:没有 JDBC 类型的方言映射:2002

Posted

技术标签:

【中文标题】Jpa Join 查询与来自两个表的数据,org.hibernate.MappingException:没有 JDBC 类型的方言映射:2002【英文标题】:Jpa Join query with Data from both tables, org.hibernate.MappingException: No Dialect mapping for JDBC type: 2002 【发布时间】:2020-11-04 10:24:48 【问题描述】:

我有这个结构

车辆品牌

@Entity
@Getter
@Setter
public class VehicleBrand 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String otherInfo;

车辆模型

@Entity
@Getter
@Setter
public class VehicleModel 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    private VehicleBrand brand;

    private String name;

    private String otherInfo;

我也有我想使用的 Dto 对象,因为我想获得一个连接查询,它将从两个表中返回数据,

模型Dto

@Getter
@Setter
public class ModelDto 

    private Long id;
    private String name;
    private long brand_id;



@Getter
@Setter
public class VehicleBrandModelDto 

    private Long id;
    private String name;
    List<ModelDto> model;

我想用 jpa 执行的查询是这样的

select vb.id , vm from vehicle_brand vb join vehicle_model vm on vb.id = vm.brand_id group by vb.id, vb, vm , vm.brand_id;

现在我在数据库上执行此操作时有 1122 条记录。但只有 85 个不同的汽车品牌

我希望得到的结果是公共类 VehicleBrandModelDto

的列表
    private Long id;
    private String name;
    List<ModelDto> model;

其中有 85 个品牌,每个对象内部都有属于该品牌的型号列表。

Currently i have tried the following solutions 

@Repository
public class VehicleBrandRepository 

    @Autowired
    private EntityManager entityManager;

    public List getSuggestionList() 
        Query nativeQuery = entityManager.createNativeQuery("select vb.name, vm as model from 
      vehicle_brand  vb join vehicle_model vm on vb.id = vm.brand_id group by vb.name, vm");
        return nativeQuery.getResultList();
    
//    public List<VehicleBrandModelDto> getSuggestionList() 
//        Query nativeQuery = entityManager.createQuery("select vb.id, vb.name, vm as model from 
         VehicleBrand  vb join VehicleModel vm on vb.id = vm.brand.id group by vb.id, vb.name, vm");
//        return nativeQuery.getResultList();
//    

createQuery 的第二个解决方案给出了 1122 条记录的结果,我尝试使用流 api 对其进行分组,但我有类转换异常,第一个查询返回错误

org.springframework.orm.jpa.JpaSystemException: No Dialect mapping for JDBC type: 2002; nested exception is org.hibernate.MappingException: No Dialect mapping for JDBC type: 2002

任何建议我可以如何实现这一点,或者这是不可能的?

数据库属性

spring.datasource.url=jdbc:postgresql://changed.compute-1.amazonaws.com:5432/changed
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=false
spring.datasource.username=changed
 spring.datasource.password=changed
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.connection.pool_size=17
spring.jpa.properties.hibernate.dialect =org.hibernate.dialect.PostgreSQLDialect
spring.datasource.driverClassName=org.postgresql.Driver

数据库版本 postgress 12

【问题讨论】:

你使用什么hibernate方言? 我正在使用 postgres @SternK hibernate中有很多postgre方言?你到底使用什么方言,你有什么 postgres 版本? 我已经通过上面的 db properties @SternK 发布了 PostgreSQL10Dialect 是 Postgres 数据库的最新休眠方言,因此在您的情况下这是正确的选择。 【参考方案1】:

不知道为什么您会收到此No Dialect mapping for JDBC type: 2002 错误。你能发布整个堆栈跟踪吗?这通常建议您使用在方言中未注册匹配 Hibernate 类型的 SQL 类型。类型代码 2002 指的是 STRUCT 类型,但您发布的模型不包含任何外来类型。我猜VehicleModel 有一些其他属性使用未正确注册的类型。你能显示VehicleModel的完整映射吗?

您可能还喜欢Blaze-Persistence Entity Views 提供的服务。

我创建了该库以允许在 JPA 模型和自定义接口或抽象类定义模型之间轻松映射,例如 Spring Data Projections on steroids。这个想法是您按照自己喜欢的方式定义目标结构(域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

使用 Blaze-Persistence Entity-Views 的用例的 DTO 模型可能如下所示:

@EntityView(VehicleBrand.class)
public interface VehicleBrandModelDto 
    @IdMapping
    Long getId();
    String getName();
    // Use this if you have an inverse one-to-many
    @Mapping("models")
    // Otherwise you can also do ad-hoc joins
    // @Mapping("VehicleModel[brand.id = VIEW(id)]")
    List<ModelDto> getModel();

    @EntityView(VehicleModel.class)
    interface ModelDto 
        @IdMapping
        Long getId();
        String getName();
        @Mapping("brand.id")
        long getBrandId();
    

查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

VehicleBrandModelDto a = entityViewManager.find(entityManager, VehicleBrandModelDto.class, id);

Spring Data 集成让您可以像使用 Spring Data Projections 一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

List<VehicleBrandModelDto> findAll();

【讨论】:

以上是关于Jpa Join 查询与来自两个表的数据,org.hibernate.MappingException:没有 JDBC 类型的方言映射:2002的主要内容,如果未能解决你的问题,请参考以下文章

用于组合来自两个表的数据的 SQL 查询

来自 JOIN 表的 PIVOT

如何将spring数据jpa规范查询中的distinct和sort与join结合起来

DQL查询数据----联表查询(left/right/inner join 区别)

DQL查询数据----联表查询(left/right/inner join 区别)

C# SqlDataAdapter 与来自多个数据库的表的 JOIN