【问题标题】:entitygraph not working - returning all the entityentitygraph 不工作 - 返回所有实体
【发布时间】:2023-03-23 04:30:01
【问题描述】:

我正在 springdata jpa 的简单场景中尝试 EntityGraph:

这个想法只是获取一个带有 id 字段的实体,并省略另一个名为 name 的字段。

这是要检索的实体:

Entity
@NamedEntityGraph(name = "Region.id",
        attributeNodes = @NamedAttributeNode("id"))
public class Region {
    @Id
    public String id;

    public String name;



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

存储库:

public interface RegionRepository extends JpaRepository<Region, String>{

    @EntityGraph(value = "Region.id")
    Region findByRegionId(String name);

}

还有一项服务:

@Service
public class RegionService {

    @Autowired
    private RegionRepository regionRepository;


    public Region getRegion(String regionId) {
        Region region = regionRepository.findByRegionId(regionId);
        return region;
    }
}

如前所述,检索整个区域。

我尝试了另一种方法,使用了更多代码。

添加了一个接口:

public interface RegionRepositoryCustom {
    Region findByRegionId(String name);
}

并用它来添加一个 impl 类:


public class RegionRepositoryImpl  implements RegionRepositoryCustom{
    @PersistenceContext
    private EntityManager em;

    @Override
    @Transactional
    public Region findByRegionId(String id) {

        EntityGraph<Region> entityGraph = (EntityGraph<Region>) em.getEntityGraph("Region.id");

        Region region = em.createQuery("select r from Region r where r.id = :id", Region.class)
                .setParameter("id", id)
                .setHint("javax.persistence.fetchgraph", entityGraph)
                .getSingleResult();

        return region;
    }

}

并尝试了这个变体:


public class RegionRepositoryImpl  implements RegionRepositoryCustom{
    @PersistenceContext
    private EntityManager em;

    @Override
    @Transactional
    public Region findByRegionId(String id) {

        //EntityGraph<Region> entityGraph = em.createEntityGraph(Region.class);
        //entityGraph.addAttributeNodes("id");

        EntityGraph<Region> entityGraph = (EntityGraph<Region>) em.getEntityGraph("Region.id");

        Map<String, Object> properties = new HashMap<>();
        properties.put("javax.persistence.fetchgraph", entityGraph);

        Region region = em.find(Region.class, id, properties);


        return region;
    }

}

同样使用 H2 和 application.properties 设置:

spring.jpa.show-sql=true

spring.jpa.properties.hibernate.format_sql=true



spring.datasource.url=jdbc:h2:mem:AZ;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;AUTO_RECONNECT=TRUE
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

spring.jpa.hibernate.ddl-auto=create-drop

spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false

这是 ide 控制台中使用的 SQL 模板:

Hibernate: 
    select
        region0_.id as id1_0_,
        region0_.name as name2_0_ 
    from
        region region0_ 
    where
        region0_.id=?

一切都没有用...

我错过了什么?

【问题讨论】:

    标签: java jpa spring-data-jpa h2 entitygraph


    【解决方案1】:

    EntityGraph 可以急切地获取两个实体之间的关系,以便仅在需要时获取它。之所以这样做,是因为连接表的性能成本可能很高,并且只有在特别需要时才应该这样做。

    如果你真的不想要这个名字,你可以将它从实体区域中移除,然后它就不会被提取。

    关于实体图的更多细节:https://thoughts-on-java.org/jpa-21-entity-graph-part-1-named-entity/

    【讨论】:

    • 我不明白它是如何解释为什么代码不起作用的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    • 2018-12-28
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    相关资源
    最近更新 更多