java Spring Data在插入时丢失了一些条目

68de4m5k  于 2023-03-11  发布在  Java
关注(0)|答案(1)|浏览(105)

bounty将在6天后过期。回答此问题可获得+50声望奖励。BANTYC希望引起更多人对此问题的关注:请说明这在引擎盖下是如何工作的,以及将来如何避免这种情况

当我尝试在PostgreSQL中保存实体的大列表(77832个元素)时。但在执行“saveAll”方法后,表中只有49207个条目(添加项目前表为空)。根据调试器,列表大小不会改变。在保存数据期间,应用程序和数据库日志中没有错误。
以下是实体类:

@Getter
@Setter
@Entity
@Table(name = "faction")
@NoArgsConstructor
@AllArgsConstructor
public class Faction {

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

    @Column(name = "name", unique = true, nullable = false)
    private String name;

    @ManyToOne(cascade = CascadeType.MERGE, optional = false)
    @JoinColumn(name = "allegiance_id", nullable = false)
    private Allegiance allegiance;

    @ManyToOne(cascade = CascadeType.MERGE, optional = false)
    @JoinColumn(name = "government_id", nullable = false)
    private Government government;

    @Column(name = "is_player_faction", nullable = false)
    private Boolean isPlayerFaction;
}
@Entity
@Table(name = "allegiance")
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Allegiance {

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

    @Column(name = "name", unique = true, nullable = false)
    private String name;
}

以及实现保存数据逻辑的方法:

public List<FactionDto> saveFactions(List<FactionDto> factionDtos) {
        var factions = factionDtos.stream()
                                  .map(factionMapper::toEntity)
                                  .toList();

        var governments = factionDtos.stream()
                                     .map(FactionDto::getGovernment)
                                     .collect(Collectors.toSet())
                                     .stream()
                                     .map(item -> new Government(null, item.getName()))
                                     .collect(Collectors.toSet());
        Map<String, Government> governmentMap = governmentRepository
                .saveAll(governments)
                .stream()
                .collect(Collectors.toMap(Government::getName, item -> item));

        var allegiances = factionDtos.stream()
                                     .map(FactionDto::getAllegiance)
                                     .collect(Collectors.toSet())
                                     .stream()
                                     .map(item -> new Allegiance(null, item.getName()))
                                     .collect(Collectors.toSet());
        Map<String, Allegiance> allegianceMap = allegianceRepository
                .saveAll(allegiances)
                .stream()
                .collect(Collectors.toMap(Allegiance::getName, allegiance -> allegiance));

        factions = factions.stream()
                           .peek(faction -> {
                               var allegiance = allegianceMap.get(faction.getAllegiance().getName());
                               faction.setAllegiance(allegiance);
                               var government = governmentMap.get(faction.getGovernment().getName());
                               faction.setGovernment(government);
                           })
                           .collect(Collectors.toList());

        return factionRepository.saveAll(factions).stream()
                                .map(factionMapper::toDto)
                                .toList();
    }

调试器显示集合中正好有77832个元素被传递来保存。没有重复的元素

在我看来,应该有相同数量的条目创建或至少错误消息,如果有冲突

hjzp0vay

hjzp0vay1#

faction.name值包含重复项。名称列是唯一的,因此仅保留唯一的名称。请在保存之前立即执行以下操作对其进行测试。

var uniqueFactionByName = factions.stream()
                                     .map(faction -> faction.name)
                                     .collect(Collectors.toSet())
System.out.println(uniqueFactionByName.size());

相关问题