gpt4 book ai didi

java - JPA Spring 忽略 @Transacational 内的延迟加载

转载 作者:行者123 更新时间:2023-12-02 09:22:18 27 4
gpt4 key购买 nike

我有一个 spring 服务类,我在其中通过 CRUD 加载 JPA 对象(目标)。该目标类具有设置为延迟加载的一对多映射。

我想在用@Transactional注释的Spring服务方法中查询这个对象,并避免加载子对象。

当我执行以下代码时,所有子数据都会被加载,并且惰性会被忽略。

        @Override
@Transactional
public boolean changeState(boolean enabled, final EventType eventType, final String deviceSerialNumber) {
final UniqueUser user = userService.getUser();
final Target target = targetRepository.findEventsByUserIdAndTenantIdAndTargetDeviceId(user.getUserId(), user.getTenantId(), deviceSerialNumber);
//here everything gets loaded
if (target == null) {
return false;
}
final List<EventHistory> events = target.getEvents().stream()
.filter(event -> event.getEventType() == eventType)
.filter(event -> event.isActive() != enabled)
.collect(Collectors.toList());
events.forEach(event -> event.setActive(enabled));
if (events.isEmpty()) {
return false;
}
return true;
}

映射:

    @ToString
@Entity
@Table(name = "target")
public class Target {

@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
@Column(name = "id", unique = true)
private UUID id;

@Column(name = "user_id")
private String userId;

@Column(name = "tenant_id")
private String tenantId;

@Column(name = "target_device_id")
private String targetDeviceId;

@Column(name = "target_type")
private TargetType targetType;

@OneToMany(mappedBy = "target", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JsonManagedReference
private List<EventHistory> events = new ArrayList<>();

public void addEvents(EventHistory event) {
events.add(event);
event.setTarget(this);
}

}

@Entity
@Data
@Table(name = "event_history")
public class EventHistory {

@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
@Column(name = "id", unique = true)
private UUID id;

@Column(name = "active")
private boolean active;


@OneToMany(mappedBy = "event", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonManagedReference
private List<EventTimestamp> timestamps = new ArrayList<>();

@ManyToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "target_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonBackReference
private Target target;

public void addTimestamps(EventTimestamp eventTimestamp) {
timestamps.add(eventTimestamp);
eventTimestamp.setEvent(this);
}

}

@Entity
@Data
@Table(name = "event_timestamp")
public class EventTimestamp {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
@Column(name = "id", unique = true)
private UUID id;


@Column(name = "due_timestamp")
private Timestamp dueTimestamp;

@Column(name = "period")
private String period;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "event_id", nullable = false)
@JsonBackReference
private EventHistory event;

所以我的问题是如何在事务注释函数内保持延迟加载?

最佳答案

我的第一个假设是错误的,即根本原因是错误地实现了存储库功能。真正的问题是 @ToString 注释。这将一对多事件集合添加到 toString()。在事务内部并访问对象时,调用 toString 并加载集合。

解决方案是通过 toString 排除集合。

@OneToMany(mappedBy = "target", cascade = CascadeType.ALL, orphanRemoval = true)
@ToString.Exclude
private List<EventHistory> events;

关于java - JPA Spring 忽略 @Transacational 内的延迟加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58609907/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com