【问题标题】:createQuery not working but createNativeQuery workscreateQuery 不工作,但 createNativeQuery 工作
【发布时间】:2017-03-07 21:22:21
【问题描述】:

伙计,我有一个很奇怪的问题。

我正在我的应用程序中设置一些端点,我有一个这样的端点:

@Path("/ioconfiguration")  
public class IOConfigurationEndPoint {  
  @EJB 
  private static IOConfigurationDAO ioConfigurationDAO;  

  @GET 
  @Produces(MediaType.APPLICATION_JSON)  
  public Response getAllIoConfigurations() {  
    ioConfigurationDAO = new IOConfigurationDAO();  
    ioConfigurationDAO.init();  
    List<IOConfiguration> list = ioConfigurationDAO.findAllIOConfiguration();  
    ioConfigurationDAO.destroy();  
    return Response.status(Response.Status.OK).entity(list).build();  
  }  
} 

想法是我需要从表中获取所有信息“IO配置”,并且我在一个名为“IO_CONFIGURATION”的表中有32行,这个实体的pojo是这样的:

@Entity 
@Indexed 
@Table(name = "IO_CONFIGURATION",  
    indexes = {@Index(columnList = "CHANNEL_NAME", name = "CHANNEL_NAME")})  
public class IOConfiguration implements Serializable {  

  private static final long serialVersionUID = 7542743172221933818L;  
  @Id 
  @GenericGenerator(name = "IOConfiguration", strategy = "uuid")  
  @GeneratedValue(generator = "IOConfiguration")  
  @Column(name = "IO_CONFIGURATION_ID")  
  private String ioConfigurationId;  

  @Field(analyze = Analyze.NO)  
  @Column(name = "CHANNEL_NAME")  
  private String channelName;  

  @Column(name = "NAME")  
  private String name;  

  @Column(name = "CONVERTION_TYPE")  
  private String conversionType;  

  @Column(name = "M_INFO")  
  private Double mInfo;  

  @Column(name = "B_INFO")  
  private Double bInfo;  

  @Column(name = "VOLTAGE_DIVIDE")  
  private String voltageDivide;  

  @Column(name = "SAMPLE_RANGE")  
  private String sampleRange;  

  @Column(name = "SAMPEL_PERIOD")  
  private Integer samplePeriod;  

  @Column(name = "STORE_ROW")  
  private Boolean storeRow;  

  @Column(name = "STORE_CONVERTED")  
  private Boolean storeConverted;  

  @Column(name = "DEFAULT_GRAPH")  
  private String defaultGraph;  

  @Column(name = "TITLE")  
  private String title;  

  @Column(name = "UNITS")  
  private String units;  

  @Column(name = "RANGE_LOWERBOUND")  
  private Integer rangeLowerbound;  

  @Column(name = "RANGE_UPPERBOUND")  
  private Integer rangeUpperbound;  

  @OneToMany(mappedBy = "ioConfiguration", fetch = FetchType.EAGER)  
  private List<Alert> alerts;  

  @OneToMany(mappedBy = "ioConfiguration", fetch = FetchType.EAGER)  
  private List<DataSeriesMeta> dataSeriesMeta;  

  @OneToMany(mappedBy = "ioConfiguration", fetch = FetchType.LAZY)  
  private List<NodeData> nodeData;  

  @Column(name = "CODE")  
  private String code;  

  @Column(name = "ACTIVE")  
  private Boolean active;  
  ...  
} 

这是我插入行的方式:

private void init() {  
    ioConfigurationDAO = new IOConfigurationDAO();  
    ioConfigurationDAO.init();  
    property = new AigatewayProperty();  

    for (int i = 1; i <= property.MAX_PORT_NUM; ++i) {  
      ioConfigurationDAO.getManager().getTransaction().begin();  
      ioConfigurationDAO.createIOConfiguration(i);  
      ioConfigurationDAO.getManager().getTransaction().commit();  
    }  
    List<IOConfiguration> list = ioConfigurationDAO.findAllIOConfiguration();  
    System.out.println(list);  
    ioConfigurationDAO.destroy();  
  } 

我可以看到从 cqlsh 控制台插入到我的数据库中的行。

我为我的 DAO 编写的所有服务,如插入、删除、修改,都可以完美运行,所以我认为 wildfly 和我的 cassandra 数据库之间的连接没有问题。

但如果我使用 HQL,查询将无法正常工作。

对于我上面提到的端点,这是我试图调用的方法:

@SuppressWarnings("unchecked")  
      public List<IOConfiguration> findAllIOConfiguration() {  
        Query query = this.getManager().createNativeQuery("select * from \"IO_CONFIGURATION\"");  
        // Query query = this.getManager().createQuery("from IOConfiguration");  
        return query.getResultList();  
      } 

如果我像第一行一样使用 createNativeQuery,端点将完美运行,这就是我从 resteasy 得到的结果:

但如果我像第二行一样使用 createQuery,端点将不起作用并给我一个空列表。

这是我的 persistence.xml 供参考:

<?xml version="1.0"?>  
    <persistence xmlns="http://java.sun.com/xml/ns/persistence" 
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
                 version="2.0">  
        <persistence-unit name="JPAService">  
            <!-- Use the Hibernate OGM provider: configuration will be transparent --> 
            <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>  
            <class>com.sensorhound.aigateway.domain.Alert</class>  
            <class>com.sensorhound.aigateway.domain.DataSeriesMeta</class>  
            <class>com.sensorhound.aigateway.domain.IOConfiguration</class>  
            <class>com.sensorhound.aigateway.domain.NodeData</class>  
            <properties>  
                <property name="hibernate.transaction.jta.platform" value="JBossAS" />  
                <property name="jboss.as.jpa.providerModule" value="org.hibernate:5.0" />  
                <property name="hibernate.ogm.datastore.provider" value="cassandra_experimental"/>  
                <property name="hibernate.ogm.datastore.host" value="127.0.0.1:9042"/>  
                <property name="hibernate.ogm.datastore.database" value="dev"/>  
            </properties>  
        </persistence-unit>  
    </persistence> 

我不知道是什么原因。很奇怪,谁能给我解释一下?

谢谢

编辑:

由于某些 stackoverflow 点问题,我无法上传有关某些数据库连接测试结果的屏幕截图。以下是一些我可以分享的关于我的数据库的可用资源。 我正在使用 cassandra,所以我使用了一个名为“dev”的键空间来存储我的所有表。 这是我在输入“describe dev”后从终端得到的结果:

CREATE KEYSPACE dev WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND persistent_writes = true;

CREATE TABLE dev."DATA_SERIES_META" ( “DATA_SERIES_META_ID”文本主键, “B_INFO”双倍, “CHANNEL_NAME”文本, “CONVERTION_TYPE”文本, “IO_CONFIGURATION”文本, “LAST_SAMPLE_TIME”文本, “M_INFO”双倍, “名称”文本, "SAMPEL_PERIOD" 整数, “SAMPLE_RANGE”文本, “START_TIME”文本, “STORE_CONVERTED”布尔值, “STORE_ROW”布尔值, “TOTAL_SAMPLE”大整数, “VOLTAGE_DIVIDE”文本)与bloom_filter_fp_chance = 0.01 AND 缓存 = {'keys': 'ALL', 'rows_per_partition': 'NONE'} 和评论 = '' AND 压缩 = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', “最大阈值”:“32”,“最小阈值”:“4”} AND 压缩 = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'} 和 crc_check_chance = 1.0 AND dclocal_read_repair_chance = 0.1 和 default_time_to_live = 0 和 gc_grace_seconds = 864000 AND max_index_interval = 2048 和 memtable_flush_period_in_ms = 0 和 min_index_interval = 128 和 read_repair_chance = 0.0 AND speculative_retry = '99PERCENTILE';在 dev."DATA_SERIES_META" 上创建索引 DATA_SERIES_META_IO_CONFIGURATION ("IO_CONFIGURATION");

CREATE TABLE dev."NODE_DATA" ( “NODEDATA_ID”文本主键, “IO_CONFIGURATION”文本, “时间”大整数, “价值”双)与bloom_filter_fp_chance = 0.01 AND 缓存 = {'keys': 'ALL', 'rows_per_partition': 'NONE'} 和评论 = '' AND 压缩 = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', “最大阈值”:“32”,“最小阈值”:“4”} AND 压缩 = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'} 和 crc_check_chance = 1.0 AND dclocal_read_repair_chance = 0.1 和 default_time_to_live = 0 和 gc_grace_seconds = 864000 AND max_index_interval = 2048 和 memtable_flush_period_in_ms = 0 和 min_index_interval = 128 和 read_repair_chance = 0.0 AND speculative_retry = '99PERCENTILE'; CREATE INDEX NODE_DATA_IO_CONFIGURATION ON dev."NODE_DATA" ("IO_CONFIGURATION");

CREATE TABLE dev."IO_CONFIGURATION" ( “IO_CONFIGURATION_ID”文本主键, “活动”布尔值, “B_INFO”双倍, “CHANNEL_NAME”文本, “代码”文本, “CONVERSION_TYPE”文本, “DEFAULT_GRAPH”文本, “M_INFO”双倍, “名称”文本, "RANGE_LOWERBOUND" 整数, "RANGE_UPPERBOUND" 整数, "SAMPLE_PERIOD" 整数, “SAMPLE_RANGE”文本, “STORE_CONVERTED”布尔值, “STORE_ROW”布尔值, “标题”文本, “单位”文本, “VOLTAGE_DIVIDE”文本)与bloom_filter_fp_chance = 0.01 AND 缓存 = {'keys': 'ALL', 'rows_per_partition': 'NONE'} 和评论 = '' AND 压缩 = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', “最大阈值”:“32”,“最小阈值”:“4”} AND 压缩 = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'} 和 crc_check_chance = 1.0 AND dclocal_read_repair_chance = 0.1 和 default_time_to_live = 0 和 gc_grace_seconds = 864000 AND max_index_interval = 2048 和 memtable_flush_period_in_ms = 0 和 min_index_interval = 128 和 read_repair_chance = 0.0 AND speculative_retry = '99PERCENTILE';在 dev."IO_CONFIGURATION" 上创建索引 IO_CONFIGURATION_CHANNEL_NAME ("CHANNEL_NAME");

CREATE TABLE dev."ALERT" ( “ALERT_ID”文本主键, “IO_CONFIGURATION”文本, “操作员”文本, “价值”双)与bloom_filter_fp_chance = 0.01 AND 缓存 = {'keys': 'ALL', 'rows_per_partition': 'NONE'} 和评论 = '' AND 压缩 = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', “最大阈值”:“32”,“最小阈值”:“4”} AND 压缩 = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'} 和 crc_check_chance = 1.0 AND dclocal_read_repair_chance = 0.1 和 default_time_to_live = 0 和 gc_grace_seconds = 864000 AND max_index_interval = 2048 和 memtable_flush_period_in_ms = 0 和 min_index_interval = 128 和 read_repair_chance = 0.0 AND speculative_retry = '99PERCENTILE'; CREATE INDEX ALERT_IO_CONFIGURATION ON dev."ALERT" ("IO_CONFIGURATION");

所以问题可能不在于我有一个重复的表。

这里是关于如何在“IO_CONFIGURATION”表中插入一行的代码:

public IOConfiguration createIOConfiguration(Integer i) {
    if (i <= 0) {
      throw new IllegalArgumentException(
          "Invalid configuration channel found when trying to create IO configuration");
    } else if (i.equals(null)) {
      throw new NullPointerException(
          "Configuration channel is null when trying to create IO configuration");
    }
    IOConfiguration emp = new IOConfiguration();
    emp.setChannelName(ChannelName.fromInt(i));
    this.getManager().persist(emp);
    return emp;
  }

我无法分享结果的屏幕截图,但我确信调用此函数后,我可以在“IO_CONFIGURATION”表中插入一行。

我现在只是在这个项目中使用 createNativeQuery。只选择一行是可以的,因为我可以在查询后指定一个 pojo 类类型,并且效果很好。

但是在使用本机查询时从表中选择数据列表实在令人沮丧。我必须手动将对象类型转换为我的 pojo,因为当我在查询后指定 pojo 类时,例如:

Query query = ioConfigurationDAO.getManager()
        .createNativeQuery("select * from \"IO_CONFIGURATION\"", IOConfiguration.class);

它只会给我数据库中的第一行,我不知道发生了什么。

如果你们需要更多信息,我愿意尽可能多地分享。

谢谢!

【问题讨论】:

  • 你并没有真正展示你的 DAO 是如何创建和插入行的,所以我们只能猜测那里发生了什么。显示为您的查询生成的 SQL,并检查您的数据库表并查看是否有两个 IO_CONFIGURATION 表。本机查询将表名放在引号中,而在实体中,您将其作为 IO_CONFIGURATION 使用,因此它们可能会在您的数据库中显示为不同的表。
  • 嗨,克里斯,我刚刚编辑了问题,谢谢!

标签: hibernate jpa hql wildfly-10 hibernate-ogm


【解决方案1】:

要使用 Cassandra 和 Hibernate OGM 执行查询,您目前需要 Hibernate Search。

文档的这一段应该为您提供所有详细信息: https://docs.jboss.org/hibernate/stable/ogm/reference/en-US/html_single/index.html#ogm-query-using-hibernate-search

简而言之,需要在实体类上添加注解org.hibernate.search.annotations.Index,在要搜索的列上添加org.hibernate.search.annotations.Field

编辑:没有意识到您已经在使用 Hibernate Search,我将扩展答案。

这意味着它只会找到被索引的实体。如果您的数据库已经包含一些实体,您需要先对它们进行索引,然后才能找到它们。

第一次启动应用程序时,您需要运行以下内容:

    FullTextSession session = Search.getFullTextSession( openSession() );
    session.createIndexer( IOConfiguration.class ).startAndWait();

这将确保在索引中添加现有实体。有关using the mass indexer 的更多详细信息,请查看 Hibernate Search 文档。

只有当你想重新创建/刷新索引时才需要这样做,当你使用 Hibernate OGM 执行 CRUD 操作时,索引会自动更新。

【讨论】:

    猜你喜欢
    • 2021-08-12
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 2018-09-05
    • 2021-11-28
    • 2018-12-19
    • 2016-06-08
    • 1970-01-01
    相关资源
    最近更新 更多