简体   繁体   English

Spring Jpa 我的实体的存储库查询 id 列两次

[英]Spring Jpa Repository Queries id column twice for my entity

I am working on a little Spring Boot app and I am having some issues understanding the Queries generated by JPA Repository.我正在开发一个小的 Spring 启动应用程序,我在理解 JPA 存储库生成的查询时遇到了一些问题。

I have 2 entities:我有 2 个实体:

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Project extends BaseEntity {
    @NotNull(message = "The project name is mandatory")
    private String name;
    private String description;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "project")
    private java.util.List<List> lists = new ArrayList<>();

    public void addList(List list) {
        lists.add(list);
        list.setProject(this);
    }

    public void removeList(List list) {
        lists.remove(list);
        list.setProject(null);
    }
}
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class List extends BaseEntity {
    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    private Project project;
}

And a base class they extend:他们扩展了一个基础 class:

package com.projectmanager.models;

import lombok.EqualsAndHashCode;
import lombok.Getter;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import java.io.Serializable;

@MappedSuperclass
@Getter
@EqualsAndHashCode
public class BaseEntity implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

I have created a repository for project entity:我为项目实体创建了一个存储库:

package com.projectmanager.repositories;

import com.projectmanager.models.Project;
import com.projectmanager.projections.ProjectHeader;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ProjectRepository extends JpaRepository<Project, Long> {
    @Query(
            "SELECT new com.projectmanager.projections.ProjectHeader( " +
                "p.id, " +
                "p.name," +
                "p.description" +
            " ) " +
            "FROM Project p")
    List<ProjectHeader> findAllProjectHeaders();
}

I am calling a service which is supposed to find a project and delete it from the DB.我正在调用一项服务,该服务应该找到一个项目并将其从数据库中删除。

public void deleteProject(Long projectId) {
    Project project = projectRepository.findById(projectId).orElseThrow(
            () -> new ProjectNotFoundException(projectId)
    );

    projectRepository.delete(project);
}

I have added in my application.properties these options:我在我的 application.properties 中添加了这些选项:

spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

When I try to call the above mentioned service, the queries printed in the console are:当我尝试调用上述服务时,控制台中打印的查询是:

select
    project0_.id as id1_1_0_,
    project0_.description as descript2_1_0_,
    project0_.name as name3_1_0_ 
from
    project project0_ 
where
    project0_.id=?

This first query corresponds to findById() call so everything is fine.第一个查询对应于findById()调用,因此一切正常。 The next one is:下一个是:

select
    lists0_.project_id as project_3_0_0_,
    lists0_.id as id1_0_0_,
    lists0_.id as id1_0_1_,
    lists0_.name as name2_0_1_,
    lists0_.project_id as project_3_0_1_ 
from
    list lists0_ 
where
    lists0_.project_id=?

This is followed by delete queries which are irrelevant for this question.接下来是与该问题无关的删除查询。

The part that I am not understanding is why id gets selected twice from the DB in the query that searches for lists associated with the project:我不理解的部分是为什么在搜索与项目关联的列表的查询中从数据库中选择了 id 两次:

lists0_.id as id1_0_0_,
lists0_.id as id1_0_1_,

Is this Spring specific or am I doing something wrong?这个 Spring 是具体的还是我做错了什么?

If you take a look on the internal implementation of delete method, it first checks if the record to be deleted exists in the table and then deletes the record.如果看一下delete方法的内部实现,它首先检查表中是否存在要删除的记录,然后删除该记录。 Hence extra select query因此额外的 select 查询

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

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