如何避免在Spring Data JPA中保存期间的select语句

时间:2017-04-27 08:45:37

标签: java spring hibernate spring-data spring-data-jpa

我有一个实体的复合主键(由3列组成)。

复合键中的2列中,1表示自动递增,另一列表示从另一个实体填充。

当我保存实体时,它执行select语句然后插入语句。 我想忽略/避免执行select语句,因为我知道实体是唯一的,只是想插入表中。

我读到在实体中有一个带@Version的字段(如@Version Long version)但是,在这种情况下,我必须在桌面上有一个我不想要的列。

执行select语句需要花费大量时间,特别是当我知道我插入的记录是唯一的时候。

[EDITED]

我的实体类是:

@Entity
public class Table implements Serializable {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private TablePK id;

    private String Name;

    private String country;
}

@Embeddable
public class TablePK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;

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

    private Integer age;
}

,日志是:

10:39:57.650 [main] DEBUG org.hibernate.SQL - select 
10:39:57.684 [main] DEBUG org.hibernate.loader.Loader - Done entity load
10:39:57.693 [main] DEBUG o.h.e.i.AbstractSaveEventListener - Generated identifier: 
10:39:57.705 [main] DEBUG o.h.e.t.internal.TransactionImpl - committing
10:39:57.706 [main] DEBUG o.h.e.i.AbstractFlushingEventListener - Processing flush-time cascades
10:39:57.707 [main] DEBUG o.h.e.i.AbstractFlushingEventListener - Dirty checking collections
10:39:57.709 [main] DEBUG o.h.e.i.AbstractFlushingEventListener - Flushed: 1 insertions, 0 updates, 0 deletions to 1 objects
10:39:57.709 [main] DEBUG o.h.e.i.AbstractFlushingEventListener - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
10:39:57.710 [main] DEBUG o.h.internal.util.EntityPrinter - Listing entities:
10:39:57.726 [main] DEBUG org.hibernate.SQL - insert into Table

任何人都可以建议。

2 个答案:

答案 0 :(得分:2)

实体映射设计错误。当您想要使用自动递增的列时,为什么还需要复合标识符?

因此,只需删除@EmbededId使用a simple auto-incremented identifier并将年龄映射为基本属性。

但是有更多值得怀疑的设计决定,例如:

  

我读过有关@Version的字段(如@Version Long版本)   在实体中,但在这种情况下,我必须有一个列   我不想要的桌子。

@Version注释的原因是长期运行的事务中的prevent lost updates或隔离级别较弱。我不确定为什么你认为它与你当前的问题有任何关系。

  

复合键中的3列,1为自动增量,其他为2   正在从另一个实体填充。

你说3列,但复合id只有2列。

我建议您阅读this comprehensive JPA and Hibernate tutorial,以便了解Hibernate的工作原理以及您应该如何使用它。

答案 1 :(得分:0)

我完全同意弗拉德的回答。但是,对于您或其他具有与您类似的情况并希望避免使用初始SELECT语句的人,您可以使您的Entity实现Persistable

@Entity
public class Table implements Persistable<TablePK> {

  @EmbeddedId
  private TablePK id;

  private String Name;

  private String country;

  @Override
  public boolean isNew() {
    return true; // this makes every entity a new one
  }
}

注意:如果可以确保您的每个save()都是唯一的实体(如作者在问题中提到的那样),请使用此选项。如果发生冲突,它将引发异常。