Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The getId method was not called #3470

Closed
lyworry opened this issue May 10, 2024 · 2 comments
Closed

The getId method was not called #3470

lyworry opened this issue May 10, 2024 · 2 comments
Labels
status: invalid An issue that we don't feel is valid

Comments

@lyworry
Copy link

lyworry commented May 10, 2024

The Class Document extends BaseEntity implements Persistable<Long> and new HashMap<Long,Document> to storage the document that have been stored to the mysql (The key is document.md5 and the value is document).
I create two repositories public interface JpaDocumentRepository extends CrudRepository<Document,Long> and public interface ElasticSearchDocumentRepository extends CrudRepository<Document,Long>.i find JpaDocumentRepository.save() was not call method 'getId()' that implement,but ElasticSearchDocumentRepository.save() will call the method getId().
If I were to call JpaDocumentRepository. save to save the two document has the same md5, will produce two records, because there is no call getId() and ElasticSearchDocumentRepository.save will insert and update, a record only.
I think implements Persistable is want to judge the object isNew,and execut update or insert.In fact,isNew only is only used to determine execut entityManager.persist(entity) or entityManager.merge(entity).entityManager.merge(entity) performs an insert or update operation depending on whether the id is empty.This does not lose the meaning of such a design?

@Setter
//@Getter
@MappedSuperclass
public class BaseEntity {

    @Id
    @GenericGenerator(name = "snowFlakeIdGenerator", type = SnowFlakeIdGenerator.class)
    @GeneratedValue(generator = "snowFlakeIdGenerator")
    public Long id;

    @CreatedDate
    private Date createdDate;

    @LastModifiedDate
    private Date lastModifiedDate;

    @CreatedBy
    private String createdBy;

    @LastModifiedBy
    private String lastModifiedBy;
}
@Setter
@Getter
@Entity
@org.springframework.data.elasticsearch.annotations.Document(indexName = "document")
public class Document extends BaseEntity implements Persistable<Long> {

    /**
     * 标题
     */
    private String title;

    @Lob
    @Column(columnDefinition = "longtext")
    @Field(type = FieldType.Text, analyzer = "ik_max_word", store = false)
    private String content;

    /**
     * 角色code列表
     */
    @Convert(converter = JpaConverterList.class)
    private List<String> roleCodeList;

    /**
     * 标签code列表
     */
    @Convert(converter = JpaConverterList.class)
    private List<String> tagCodeList;

    /**
     * 文本摘要
     */
    private String md5;

    @Nullable
    @Override
    public Long getId() {
        Document document = Cache.cacheMap.get(md5);
        if (document != null) {
            return document.id;
        }
        return this.id;
    }

    @Override
    public boolean isNew() {
        return Cache.cacheMap.get(md5) == null;
    }

}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label May 10, 2024
@mp911de
Copy link
Member

mp911de commented May 13, 2024

Persistable is a Spring Data API to determine the identifier and whether an object is new or not. Persistable is only used by Spring Data modules in which we fully control the object lifecycle such as Elasticsearch.

JPA handles object lifecycles on its own with the concept of attached entities hence Spring Data JPA doesn't make use of Persistable for inserts vs. updates, instead, what you already found, whether to call EntityManager.merge(…) vs. EntityManager.persist(…).

Generally speaking, if you use a single cache (Cache.cacheMap.get(md5)) for two persistence technologies, after associating the object with your cache, all related store modules will use the same outcome for isNew.

Ideally, you use the md5 value as primary key if that is what you're looking for.

@mp911de mp911de closed this as not planned Won't fix, can't repro, duplicate, stale May 13, 2024
@mp911de mp911de added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged labels May 13, 2024
@lyworry
Copy link
Author

lyworry commented May 13, 2024

Persistable seem to be unuseful in spring data jpa.All operations depend on whether id has value.I can't imagine what can i do with Persistable .I think spring data jpa and spring data elasticsearch,they all belong to spring data,
they implements Persistable,They should have the same behavior

  1. if document ’s id has value and isNew=true will throw exception, isNew=false will select by id and update;
  2. if document ’s id is null and isNew=true will insert,isNew=false wll also insert;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

3 participants