简体   繁体   English

如何在 Spring Data JPA 中保存期间避免选择语句

[英]How to avoid select statement during save in Spring Data JPA

I have a composite primary key (made of 3 columns) for an entity.我有一个实体的复合主键(由 3 列组成)。

Out of 2 columns from the composite key, 1 is auto increment and another is getting populated from another entity.在复合键的 2 列中,1 是自动增量,另一个是从另一个实体填充的。

when I save the entity, it executes select statement and then insert statement.当我保存实体时,它会执行 select 语句,然后执行 insert 语句。 I want to ignore/avoid execution of select statement as I know that the entity are unique and simply want to insert into the table.我想忽略/避免执行 select 语句,因为我知道实体是唯一的,只是想插入到表中。

I read about having a field with @Version (like @Version Long version ) in the entity however, in that case, I will have to have a column on the table as well which I don't want.我读到在实体中有一个带有 @Version (如@Version Long version )的字段,但是,在这种情况下,我将不得不在表上有一列我不想要的列。

The execution of select statement taking lots of time especially when I know that the records I am inserting are unique. select 语句的执行需要很多时间,尤其是当我知道我插入的记录是唯一的时。

[EDITED] [编辑]

my entity class is:我的实体类是:

@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;
}

and the log is:日志是:

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

Can anyone please suggest.任何人都可以请建议。

The entity mapping design is wrong.实体映射设计错误。 Why do you need a composite identifier when you already want to use an auto-incremented column?当您已经想使用自动递增列时,为什么还需要复合标识符?

So, just remove the @EmbededId use a simple auto-incremented identifier and map the age as a basic attribute.因此,只需使用简单的自动递增标识符删除@EmbededId并将年龄映射为基本属性。

But there are more questionable design decisions, like:但是还有更多有问题的设计决策,例如:

I read about having a field with @Version (like @Version Long version) in the entity however in that case I will have to have a column in the table as well which I dont want.我读到在实体中有一个带有@Version(如@Version Long 版本)的字段,但是在这种情况下,我将不得不在表中有一列我不想要的列。

The reason of the @Version annotation is to prevent lost updates in long-running transactions or weaker isolation levels. @Version注释的原因是为了防止在长时间运行的事务或较弱的隔离级别中丢失更新 I'm not sure why do you think it has anything to do with your current problem.我不确定为什么您认为这与您当前的问题有关。

out of 3 column from composite key, 1 is auto increment and other two are getting populated from another entity.在复合键的 3 列中,1 是自动增量,另外两个是从另一个实体填充的。

You say 3 columns, but the composite id has only 2 columns.你说 3 列,但复合 id 只有 2 列。

I suggest you read this comprehensive JPA and Hibernate tutorial so that you understand how Hibernate works and how you should be using it.我建议您阅读这篇综合性的 JPA 和 Hibernate 教程,以便您了解 Hibernate 的工作原理以及应该如何使用它。

I completely Agree with Vlad's answer.我完全同意弗拉德的回答。 However for you or someone else who has a scenario similar to yours and wants to avoid the initial SELECT statement, you can make your Entity implement Persistable但是,对于您或其他与您有类似情况并希望避免使用初始 SELECT 语句的人,您可以使您的实体实现 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
  }
}

NOTE: Use this if you can make the guarantee that your every save() will be a unique entity like the author has mentioned in the question.注意:如果您可以保证您的每个 save() 都是一个独特的实体,就像作者在问题中提到的那样,请使用它。 It will throw exceptions in case of conflicts.如果发生冲突,它将抛出异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM