【问题标题】:Hibernate Native QueryHibernate 原生查询
【发布时间】:2021-10-12 21:53:10
【问题描述】:

我想编写一个本地查询“从表中选择 *”我的存储库。表名与实体名不同。

运行查询时,

1 如果我把它返回的实体名称表未找到。

2 如果我将表名放入查询中,我会得到 Validation failed for query。

查询是

@Transactional
    @Query(
            value = "Select * from " +
                    "TariffPacks r2 where r2.TariffID = :tariffId " +
                    "and r2.regionname = :regionname " +
                    "and r2.category = :category " +
                    "and r2.amount = :amount " +
                    "and r2.operator = :operator", nativeQuery = true
    )
    List<TariffPacks> findByTariffID_RegionName_Category_Amount_Operator(
            @Param("tariffId") Long tariffId,
            @Param("regionname") String regionname,
            @Param("category") String category,
            @Param("amount") Integer amount,
            @Param("operator") String operator
    );

    @Transactional
    @Modifying
    @Query(
            value = "Delete from " +
                    "TariffPacks r2 where r2.TariffID = :tariffId " +
                    "and r2.regionname = :regionname " +
                    "and r2.category = :category " +
                    "and r2.amount = :amount " +
                    "and r2.operator = :operator"
    )
    List<TariffPacks> deleteByTariffID_RegionName_Category_Amount_Operator(
            @Param("tariffId") Long tariffId,
            @Param("regionname") String regionname,
            @Param("category") String category,
            @Param("amount") Integer amount,
            @Param("operator") String operator
    );

如果我使用“Select * from TariffPacks r2 ..., nativeQuery = true”,我会收到错误 Tariffpacks 不存在。 如果我使用“Select * from RECHARGEDATAPACKS r2 .., nativeQuery = true”,我会在 Hibernate 中收到验证错误。

实体:

import lombok.*;

import javax.persistence.*;
import java.time.LocalDateTime;

@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "RECHARGEDATAPACKS")
public class TariffPacks {
    @Id
    @GeneratedValue(generator = "RECHARGEDATAPACKS_SEQ")
    @SequenceGenerator(name = "RECHARGEDATAPACKS_SEQ", sequenceName = "RECHARGEDATAPACKS_SEQ", allocationSize = 1)
    // @GeneratedValue(strategy = GenerationType.AUTO)
    private Long packid;

    private Long TariffID;
    private String operator;
    private String operatoralias;
    private String regionname;
    private String regionalias;
    private String category;
    private Integer amount;
    private String talktime;
    private String validity;
    private String description;
    private String billercategory;
    private String updatedOn;
    private String entryDate;

}

我有三个问题: 1 如何在使用nativeQuery = true时让hibernate查找表名(RECHARGEDATAPACKS)?

2 我可以在不使用 nativeQuery = true 的情况下在 Hibernate 中编写“Select *”吗?我想我必须写下所有列名,如 TariffId、Operator、region ..,但我希望返回实体。如何将所有列映射到输出中的实体?

3 有没有其他方法可以编写单个列名并将它们映射到实体类?比如我写了 Select TariffId, Operator, region ..,我怎么能直接获取关税ID?

【问题讨论】:

  • 您必须使用表名。验证错误是什么样子的?
  • 它现在可以使用表名而不是实体名,不知道为什么它一直抛出错误。
  • 你的问题回答了吗?
  • 是的,但其他问题仍然存在。
  • @SimonMartinelli 我间歇性遇到的休眠错误是: 引起:java.lang.IllegalStateException:org.hibernate.hql.internal.QueryExecutionRequestException:不支持 DML 操作 [从 com.telecomwatch 删除.process.entity.TariffPacks r2 where r2.TariffID = :tariffId and r2.regionname = :regionname and r2.category = :category and r2.amount = :amount and r2.operator = :operator] at org.hibernate.query。 internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1607) at org.hibernate.query.Query.getResultList(Query.java:165)

标签: oracle spring-boot hibernate java-8


【解决方案1】:

使用本机查询时,您必须使用表名,而不是实体名。您还必须使用数据库列名,而不是 java 字段名。

当使用非本地查询(称为 JPQL 或在休眠中特别是 HQL)时,您必须使用实体和字段名称。而不是select * from Entity e ...,语法是select e from Entity e ...

【讨论】:

  • 我间歇性地得到的休眠错误是:引起:java.lang.IllegalStateException:org.hibernate.hql.internal.QueryExecutionRequestException:不支持DML操作[从com.telecomwatch.process删除.entity.TariffPacks r2 where r2.TariffID = :tariffId and r2.regionname = :regionname and r2.category = :category and r2.amount = :amount and r2.operator = :operator] at org.hibernate.query.internal。 AbstractProducedQuery.list(AbstractProducedQuery.java:1607) at org.hibernate.query.Query.getResultList(Query.java:165)
  • 问题似乎是,如果我没有删除的返回类型为 void 类型,则会引发此错误。如何重新构建查询以获取删除的行数?
  • 对于删除/更新查询,您不能使用getResultListgetSingleResult。您必须使用executeUpdate,因为结果不是行数,而是受影响的行数。
【解决方案2】:

1 如果我把它返回的实体名称表找不到。

如果你使用 nativeQuery = true 那么你必须写 Table name

    @Transactional
@Query(value = "Select * from " + "RECHARGEDATAPACKS r2 where r2.TariffID = :tariffId "
        + "and r2.regionname = :regionname " + "and r2.category = :category " + "and r2.amount = :amount "
        + "and r2.operator = :operator", nativeQuery = true)
List<TariffPacks> findByTariffID_RegionName_Category_Amount_Operator(@Param("tariffId") Long tariffId,
        @Param("regionname") String regionname, @Param("category") String category, @Param("amount") Integer amount,
        @Param("operator") String operator);

2 如果我将表名放入查询中,我会得到 Validation failed for query。

我尝试使用相同的代码并且工作正常。请指定确切的错误/异常。

1 如何在使用 nativeQuery = true 时让休眠查找表名 (RECHARGEDATAPACKS)?

如果使用 nativeQuery = true,那么您只需提供 表名,否则您可以编写 HQL/JPQL 和实体类名

2 我可以在不使用nativeQuery = true 的情况下在Hibernate 中编写“Select *”吗?我想我必须写下所有列名,如 TariffId、Operator、region ..,但我希望返回实体。如何将所有列映射到输出中的实体?

你可以这样写:

@Query(value = "from " + "TariffPacks r2 where r2.TariffID = :tariffId " + "and r2.regionname = :regionname " + "and r2.category = :category " + " and r2.amount = :amount " + "and r2.operator = :operator")

3 有没有其他方法可以编写单个列名并将它们映射到实体类?比如如果我写 Select TariffId, Operator, region ..,我怎么能直接获取关税 ID?

你可以这样做:

    @Query(value = "select TariffID, category from RECHARGEDATAPACKS where packid = :packid", nativeQuery = true)
List<Object[]> someMethodName(Long packid);

然后你就可以提取了。

【讨论】:

  • 问题似乎是,如果我没有删除的返回类型为 void 类型,则会引发此错误。如何重新构建查询以获取删除的行数?
猜你喜欢
  • 2014-07-15
  • 1970-01-01
  • 1970-01-01
  • 2016-10-11
  • 2018-11-30
  • 2011-08-28
  • 2012-07-15
  • 2015-07-15
  • 1970-01-01
相关资源
最近更新 更多