@Version from org.springframework.data.mybatis.annotations.Version does not get incremented by 1 on update due to condition that break the query

huangapple 未分类评论47阅读模式
英文:

@Version from org.springframework.data.mybatis.annotations.Version does not get incremented by 1 on update due to condition that break the query

问题

Description

在一个 Spring Boot 1.5.9 应用程序中,

我在 @Entity 上使用了 org.springframework.data.mybatis.annotations.Version 注解,将其放在 version 属性上,以便在每次更新时自动递增版本,但这却导致我的应用程序出现问题。

错误信息为:

update effect 0 row, maybe version control lock occurred.

我可以看到请求以以下方式结束:

"version"="version"+1,
where 
"id"=21
 and "version"=null 

and "version"=null 导致整个请求未编辑任何行。

这是实体的一个示例:


CREATE TABLE "cm_company_postal_address"
(
    "id"                      BIGSERIAL    NOT NULL,
    "note"                    VARCHAR(255)          DEFAULT NULL,
    "city"                    VARCHAR(255) NOT NULL,
    "postal_code"             BIGINT                DEFAULT NULL,
    "c_ref_country_id"        BIGINT       NOT NULL,
    "cm_company_id"              BIGINT       NOT NULL,
    "street_address_line1"   VARCHAR      NOT NULL,
    "street_address_line2"   VARCHAR               DEFAULT NULL,
    "post_box"                VARCHAR(20)           DEFAULT NULL,
    "version"                 BIGINT                DEFAULT NULL,
    "created_date_time"       TIMESTAMPTZ           DEFAULT NULL,
    "created_by_id"           BIGINT                DEFAULT NULL,
    "last_modified_date_time" TIMESTAMPTZ           DEFAULT NULL,
    "last_modified_by_id"     BIGINT                DEFAULT NULL,
    "deleted"                 BOOLEAN      NOT NULL DEFAULT FALSE,
    PRIMARY KEY ("id"),
    CONSTRAINT company_id_fk FOREIGN KEY ("cm_company_id") REFERENCES "cm_company" ("id")
);

这是 Java 类:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.data.mybatis.annotations.Column;
import org.springframework.data.mybatis.annotations.Condition;
import org.springframework.data.mybatis.annotations.Conditions;
import org.springframework.data.mybatis.annotations.Entity;
import static org.springframework.data.repository.query.parser.Part.Type.CONTAINING;

@Data
@JsonIgnoreProperties("new")
@Entity(table = "cm_company_postal_address")
@EqualsAndHashCode(callSuper = false)
public class PostalAddress {
    @Id(strategy = AUTO)
    private Long id;
    private String description;
	@Version
	private Integer version;
	@CreatedDate
	@JsonUnwrapped
    @JdbcType(TIMESTAMP)
	private Instant createdDateTime;
	@LastModifiedDate
	@JsonUnwrapped
    @JdbcType(TIMESTAMP)
	private Instant lastModifiedDateTime;
	@CreatedBy
	private Long createdById;
	@LastModifiedBy
	private Long lastModifiedById;
    @JsonProperty(value = "deleted")
	private Boolean deleted = false;
    @Column(name = "cm_company_id")
    private Long companyId;
    private String city;
    private Long postalCode;
    private Long countryId;
    private String streetAddressLine1;
    private String streetAddressLine2;
    private String postBox;

}

这是所示实体的 @Repository

import com.kopaxgroup.api.companyManagement.domain.postalAddress.geography.PostalAddress;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.data.mybatis.repository.support.MybatisRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource(exported = false)
public interface PostalAddressRepository extends MybatisRepository<PostalAddress, Long> {

}

这是同一实体的服务接口:

import com.kopaxgroup.api.companyManagement.domain.postalAddress.geography.PostalAddress;
import org.springframework.data.support.CrudService;


public interface PostalAddressService extends CrudService<PostalAddress, Long> {

}

以及它的实现:

import com.kopaxgroup.api.companyManagement.domain.postalAddress.geography.PostalAddress;
import com.kopaxgroup.api.companyManagement.repository.PostalAddressRepository;
import com.kopaxgroup.api.companyManagement.service.PostalAddressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.support.AbstractCrudService;
import org.springframework.stereotype.Service;

@Service
public class PostalAddressServiceImpl extends AbstractCrudService<PostalAddressRepository, PostalAddress, Long> implements PostalAddressService {

    @Autowired
    public PostalAddressServiceImpl(PostalAddressRepository repository) {
        super(repository);
    }

以及这是如何更新实体的方式:

import com.kopaxgroup.api.companyManagement.domain.postalAddress.geography.PostalAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/postal-address")
public class PostalAddressController {

  @Autowired
  private PostalAddressService postalAddressService;

  @PutMapping("/{id}")
  @ResponseStatus(HttpStatus.NO_CONTENT)
  void modify(@PathVariable("id") Long id, @RequestBody PostalAddress entity) {
    entity.setId(id);
    postalAddressService.updateIgnore(entity);
  }
}

期望

我期望这个实体的 version 列在每次更新时都会递增。

结果

然而,每次更新都会为版本列保留 null 值。

问题

  • 如何防止 spring-data-mybatis 在请求末尾添加 and "version"=null

版本

英文:

Description

In a Spring Boot 1.5.9 application,

I am using org.springframework.data.mybatis.annotations.Version annotation within an @Entity on version attribute to get a version incremented on each update, but it keep breaking my application.

The error is:

 update effect 0 row, maybe version control lock occurred.

I can see that the request end with:

&quot;version&quot;=&quot;version&quot;+1,
where 
&quot;id&quot;=21
 and &quot;version&quot;=null 

and &quot;version&quot;=null cause the whole request to edit 0 row.

This is an example of entity:


CREATE TABLE &quot;cm_company_postal_address&quot;
(
    &quot;id&quot;                      BIGSERIAL    NOT NULL,
    &quot;note&quot;                    VARCHAR(255)          DEFAULT NULL,
    &quot;city&quot;                    VARCHAR(255) NOT NULL,
    &quot;postal_code&quot;             BIGINT                DEFAULT NULL,
    &quot;c_ref_country_id&quot;        BIGINT       NOT NULL,
    &quot;cm_company_id&quot;              BIGINT       NOT NULL,
    &quot;street_address_line1&quot;   VARCHAR      NOT NULL,
    &quot;street_address_line2&quot;   VARCHAR               DEFAULT NULL,
    &quot;post_box&quot;                VARCHAR(20)           DEFAULT NULL,
    &quot;version&quot;                 BIGINT                DEFAULT NULL,
    &quot;created_date_time&quot;       TIMESTAMPTZ           DEFAULT NULL,
    &quot;created_by_id&quot;           BIGINT                DEFAULT NULL,
    &quot;last_modified_date_time&quot; TIMESTAMPTZ           DEFAULT NULL,
    &quot;last_modified_by_id&quot;     BIGINT                DEFAULT NULL,
    &quot;deleted&quot;                 BOOLEAN      NOT NULL DEFAULT FALSE,
    PRIMARY KEY (&quot;id&quot;),
    CONSTRAINT company_id_fk FOREIGN KEY (&quot;cm_company_id&quot;) REFERENCES &quot;cm_company&quot; (&quot;id&quot;)
);

This is the java class:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.data.mybatis.annotations.Column;
import org.springframework.data.mybatis.annotations.Condition;
import org.springframework.data.mybatis.annotations.Conditions;
import org.springframework.data.mybatis.annotations.Entity;
import static org.springframework.data.repository.query.parser.Part.Type.CONTAINING;

@Data
@JsonIgnoreProperties(&quot;new&quot;)
@Entity(table = &quot;cm_company_postal_address&quot;)
@EqualsAndHashCode(callSuper = false)
public class PostalAddress {
    @Id(strategy = AUTO)
    private Long id;
    private String description;
	@Version
	private Integer version;
	@CreatedDate
	@JsonUnwrapped
    @JdbcType(TIMESTAMP)
	private Instant createdDateTime;
	@LastModifiedDate
	@JsonUnwrapped
    @JdbcType(TIMESTAMP)
	private Instant lastModifiedDateTime;
	@CreatedBy
	private Long createdById;
	@LastModifiedBy
	private Long lastModifiedById;
    @JsonProperty(value = &quot;deleted&quot;)
	private Boolean deleted = false;
    @Column(name = &quot;cm_company_id&quot;)
    private Long companyId;
    private String city;
    private Long postalCode;
    private Long countryId;
    private String streetAddressLine1;
    private String streetAddressLine2;
    private String postBox;

}

This is my @Repository for the presented entity:

import com.kopaxgroup.api.companyManagement.domain.postalAddress.geography.PostalAddress;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.data.mybatis.repository.support.MybatisRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource(exported = false)
public interface PostalAddressRepository extends MybatisRepository&lt;PostalAddress, Long&gt; {

}

This is the service interface for the same entity:

import com.kopaxgroup.api.companyManagement.domain.postalAddress.geography.PostalAddress;
import org.springframework.data.support.CrudService;


public interface PostalAddressService extends CrudService&lt;PostalAddress, Long&gt; {

}

And it's implementation:

import com.kopaxgroup.api.companyManagement.domain.postalAddress.geography.PostalAddress;
import com.kopaxgroup.api.companyManagement.repository.PostalAddressRepository;
import com.kopaxgroup.api.companyManagement.service.PostalAddressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.support.AbstractCrudService;
import org.springframework.stereotype.Service;

@Service
public class PostalAddressServiceImpl extends AbstractCrudService&lt;PostalAddressRepository, PostalAddress, Long&gt; implements PostalAddressService {

    @Autowired
    public PostalAddressServiceImpl(PostalAddressRepository repository) {
        super(repository);
    }

And this is how I update the entity:

import com.kopaxgroup.api.companyManagement.domain.postalAddress.geography.PostalAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(&quot;/postal-address&quot;)
public class PostalAddressController {

  @Autowired
  private PostalAddressService postalAddressService;

  @PutMapping(&quot;/{id}&quot;)
  @ResponseStatus(HttpStatus.NO_CONTENT)
  void modify(@PathVariable(&quot;id&quot;) Long id, @RequestBody PostalAddress entity) {
    entity.setId(id);
    postalAddressService.updateIgnore(entity);
  }
}

Expected

I expect to have the version column of this entity to be incremented on each update.

Result

Instead, each update keep a null value for version column.

Question

  • How can I prevent spring-data-mybatis from appending and &quot;version&quot;=null at the end of the request?

Version

答案1

得分: 0

Spring-data还有它自己的版本注解:org.springframework.data.annotation.Version。这个注解在spring-data-mybatis库中使用。

英文:

Spring-data has also its own version annotation: org.springframework.data.annotation.Version. This annotation is used in spring-data-mybatis lib.

huangapple
  • 本文由 发表于 2020年4月10日 22:57:20
  • 转载请务必保留本文链接:https://java.coder-hub.com/61142951.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定