【问题标题】:update query using @query in spring boot not working eventhough no error is showing即使没有显示错误,在 Spring Boot 中使用 @query 更新查询也不起作用
【发布时间】:2017-07-30 02:54:30
【问题描述】:

我正在使用 h2 数据库的 spring boot 应用程序(MYSQL 投诉)

我有以下存储库:

public interface IGrpAvgMetricTimeSeriesRepository extends
    CrudRepository<GrpAvgMetricTimeSeriesEntity, GrpAvgMetricTimeSeriesEntityPK> {

    @Transactional
    @Modifying(clearAutomatically = true)
    @Query(
        "update GrpAvgMetricTimeSeriesEntity ge Set ge.sampleCount = ge.sampleCount + 1 ,ge.sumVal = ge.sumVal + ?1 "
            + "where ge.groupId = ?2 and ge.metric = ?3 and ge.normalizedTimeStamp = ?4 ")
    void updateSumAndCounter(double value, String grpId, String metric, long normalizedTimeStamp);

    @Query("select g from GrpAvgMetricTimeSeriesEntity g where g.normalizedTimeStamp >= ?1 "
        + "and g.normalizedTimeStamp <= ?2 and g.groupId = ?3 and g.metric = ?4 order by g.normalizedTimeStamp ")
    List<GrpAvgMetricTimeSeriesEntity> getPointsBetween(long fromTime, long toTime, String grpId,
        String metric);
}

使用以下实体:

@Entity
@IdClass(GrpAvgMetricTimeSeriesEntityPK.class)
public class GrpAvgMetricTimeSeriesEntity {

    @NotNull
    @Id
    private String groupId;

    @NotNull
    @Id
    private String metric;


    @NotNull
    @Id
    private long normalizedTimeStamp;

    @NotNull
    private double sumVal;

    @NotNull
    private long sampleCount;


    public GrpAvgMetricTimeSeriesEntity(){
        //For mapper
    }

    public GrpAvgMetricTimeSeriesEntity(String groupId, String metric, long normalizedTimeStamp,
        float sumVal, long sampleCount) {
        this.groupId = groupId;
        this.metric = metric;
        this.normalizedTimeStamp = normalizedTimeStamp;
        this.sumVal = sumVal;
        this.sampleCount = sampleCount;
    }

    public String getGroupId() {
        return groupId;
    }

    public void setGroupId(String groupId) {
        this.groupId = groupId;
    }

    public String getMetric() {
        return metric;
    }

    public void setMetric(String metric) {
        this.metric = metric;
    }

    public long getNormalizedTimeStamp() {
        return normalizedTimeStamp;
    }

    public void setNormalizedTimeStamp(long normalizedTimeStamp) {
        this.normalizedTimeStamp = normalizedTimeStamp;
    }

    public double getSumVal() {
        return sumVal;
    }

    public void setSumVal(float sumVal) {
        this.sumVal = sumVal;
    }

    public long getSampleCount() {
        return sampleCount;
    }

    public void setSampleCount(long sampleCount) {
        this.sampleCount = sampleCount;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        GrpAvgMetricTimeSeriesEntity that = (GrpAvgMetricTimeSeriesEntity) o;
        return normalizedTimeStamp == that.normalizedTimeStamp &&
            Double.compare(that.sumVal, sumVal) == 0 &&
            sampleCount == that.sampleCount &&
            Objects.equal(groupId, that.groupId) &&
            Objects.equal(metric, that.metric);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(groupId, metric, normalizedTimeStamp, sumVal, sampleCount);
    }

    @Override
    public String toString() {
        return "GrpAvgMetricTimeSeriesEntity{" +
            "groupId='" + groupId + '\'' +
            ", metric='" + metric + '\'' +
            ", normalizedTimeStamp=" + normalizedTimeStamp +
            ", sumVal=" + sumVal +
            ", sampleCount=" + sampleCount +
            '}';
    }
}

以下sql脚本:

create table host_time_series_entity (
    time_stamp long not null,
    host_name varchar(255) not null,
    metric_name varchar(255) not null,
    metric_value double(255),
    primary key (time_stamp, host_name, metric_name)
    );

create table grp_avg_metric_time_series_entity (group_id varchar(255) not null, metric varchar(255) not null, normalized_time_stamp bigint not null, sum_val DOUBLE not null,sample_count bigint not null, primary key(group_id, metric, normalized_time_stamp));

当应用程序运行并执行此查询时,不会引发异常。

在 Jpa 单元测试中,一切都在通过。

H2 正在创建具有所有正确列的所有模式..

但是,在执行查询后,在 h2 中没有更新新行(第二个表的其他存储库,它只是执行“保存”查询。)

有什么问题??

感谢您的帮助!!

更新

我认为的问题是我需要先检查表中是否已经存在该行 - 如果不创建一个,则更新现有的。

如何使用 @Query 做到这一点?我看到了@SQLinsert 的东西,但我无法让它工作!!

帮助 :(

【问题讨论】:

    标签: mysql spring-boot spring-data h2


    【解决方案1】:

    很难说这里有什么问题。

    我看到两个主要的候选者:一些事务问题,因此更改确实发生了,但没有被提交。或者您的 where 子句已关闭。

    为了调试这个激活 SQL 日志和事务日志。

    此外,删除 where 子句并检查没有 where 子句的更新是否有效。如果确实把where子句的元素加回来,一一找出问题的条件。

    【讨论】:

    • 我认为这是因为我在尝试更新之前不检查该行是否存在!你知道我该怎么做吗?类似“在重复密钥更新时插入...”?
    • 你可以有一个 int 的返回类型并获取更新的行数(我认为)。如果为 0,则进行插入。
    • 但这效率不高,我不想等待来自 dababase 的回复,而只是更新......不是吗?
    • 一些数据库支持 upsert ...或者您可以跟踪它是否已经存在于客户端的数据库中。这真的是一个完全不同的问题。请在 SO 上单独询问
    猜你喜欢
    • 2021-03-31
    • 2020-05-09
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2021-11-29
    • 2016-12-15
    相关资源
    最近更新 更多