You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot OneToMany关联查询返回重复主对象的问题求助

Spring Boot OneToMany关联查询返回重复主对象的问题求助

我在Spring Boot项目里遇到了个小问题,为了复现问题专门建了个测试项目。我有两个实体类是OneToMany的关联关系,但查询接口返回结果时,主对象Test2会根据关联的Test3列表元素数量重复出现,想请教大家怎么解决这个问题🥺

实体类代码

Test2 实体

@Entity
@Table(name = "test2")
@Getter
@Setter
@ToString
public class Test2 {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Fetch(FetchMode.SUBSELECT)
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "relation_id", referencedColumnName = "id")
    private List<Test3> test3 = new ArrayList<>();
}

Test3 实体

@Entity
@Table(name = "test3")
@Getter
@Setter
@ToString
public class Test3 {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id3;

    private String test2;
}

查询结果对比

实际返回结果

[
    {
        "id": 1,
        "test3": [
            {
                "id3": 1,
                "test2": "0"
            }
        ]
    },
    {
        "id": 2,
        "test3": [
            {
                "id3": 2,
                "test2": "0"
            },
            {
                "id3": 3,
                "test2": "1"
            },
            {
                "id3": 4,
                "test2": "3"
            }
        ]
    },
    {
        "id": 2,
        "test3": [
            {
                "id3": 2,
                "test2": "0"
            },
            {
                "id3": 3,
                "test2": "1"
            },
            {
                "id3": 4,
                "test2": "3"
            }
        ]
    },
    {
        "id": 2,
        "test3": [
            {
                "id3": 2,
                "test2": "0"
            },
            {
                "id3": 3,
                "test2": "1"
            },
            {
                "id3": 4,
                "test2": "3"
            }
        ]
    },
    {
        "id": 3,
        "test3": [
            {
                "id3": 5,
                "test2": "11"
            }
        ]
    }
]

预期返回结果

[
    {
        "id": 1,
        "test3": [
            {
                "id3": 1,
                "test2": "0"
            }
        ]
    },
    {
        "id": 2,
        "test3": [
            {
                "id3": 2,
                "test2": "0"
            },
            {
                "id3": 3,
                "test2": "1"
            },
            {
                "id3": 4,
                "test2": "3"
            }
        ]
    },
    {
        "id": 3,
        "test3": [
            {
                "id3": 5,
                "test2": "11"
            }
        ]
    }
]

仓库与控制器代码

TestRepo 仓库接口

public interface TestRepo extends JpaRepository<Test2, Long> {

    @Query(value = "SELECT * FROM test2 t2 JOIN test3 t3 ON t2.id = t3.relation_id", nativeQuery = true)
    List<Test2> getTest2();
}

TestContro 控制器

@RestController
public class TestContro {

    Logger logger = Logger.getLogger(TestContro.class.getName());

    @Autowired
    TestRepo testRepo;

    @GetMapping("/get")
    ResponseEntity<?> findAllTest() {
        return new ResponseEntity<>(testRepo.getTest2(), HttpStatus.OK);
    }
}

后续尝试与遇到的问题

感谢大家的回复,我尝试了一些方案,但遇到了新问题:

  • 我去掉了@Fetch(FetchMode.SUBSELECT),并把查询语句改成@Query("select t2 from Test2 t2 join fetch t2.test3"),但去掉nativeQuery = true后直接报错了,错误信息如下:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testContro': Unsatisfied dependency expressed through field 'testRepo': Error creating bean with name 'testRepo' defined in com.rpImmo.BackServer.repository.TestRepo defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Could not create query for public abstract java.util.List com.rpImmo.BackServer.repository.TestRepo.getTest2(); Reason: Validation failed for query for method public abstract java.util.List com.rpImmo.BackServer.repository.TestRepo.getTest2()
  • 另外,我没法直接用简单的全量查询,因为后续需要编写带特定条件的自定义查询,所以这个方案暂时不适用。

后来我好像找到问题所在了,等下会去尝试(问题应该出在查询语句里,需要把表名test2改成Java实体类名Test2)

备注:内容来源于stack exchange,提问作者Jérôme Martineau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 14:55:27