admin管理员组文章数量:1023868
I have two entities:
@Setter
@Getter
@Entity
@Table(name = "Task")
@NoArgsConstructor
public class TaskEntity implements AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "mapName")
private String mapName;
@Column(name = "mapPath")
private String mapPath;
@Column(name = "mapCost")
private String mapCost;
@Column(name = "mapCostResult")
private String mapCostResult;
@Enumerated(EnumType.STRING)
@Column(name = "taskStatus")
private TaskStatus taskStatus;
@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "ticketId")
private TicketEntity ticket;
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(
name = "Builder_Task",
joinColumns = @JoinColumn(name = "taskId"),
inverseJoinColumns = @JoinColumn(name = "builderDiscordId")
)
private Set<BuilderEntity> builders = new HashSet<>();
public @NotNull TaskEntity addBuilder(@NotNull BuilderEntity builderEntity) {
builders.add(builderEntity);
return this;
}
public @NotNull TaskEntity removeBuilder(@NotNull BuilderEntity builderEntity) {
builders.remove(builderEntity);
return this;
}
}
and
@Setter
@Getter
@Entity
@Table(name = "Ticket")
@NoArgsConstructor
public class TicketEntity implements AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "channelId", unique = true)
private String channelId;
@Column(name = "creatorName")
private String creatorName;
@Column(name = "creationDate")
@CreationTimestamp
private Timestamp creationDate;
@Column(name = "deadline", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private Timestamp deadline;
@Column(name = "available")
private boolean available;
@Column(name = "mapsAmount")
private int mapsAmount;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true)
@OrderColumn(name = "ticketId")
private Set<TaskEntity> tasks = new HashSet<>();
public @NotNull TicketEntity addTask(@NotNull TaskEntity taskEntity) {
tasks.add(taskEntity);
return this;
}
public @NotNull TicketEntity removeTask(@NotNull TaskEntity taskEntity) {
tasks.remove(taskEntity);
return this;
}
}
Here are my service and repository:
public class TicketRepository implements CRUDRepository<TicketEntity, Integer> {
// Only needed function for question
@Override
public @NotNull TicketEntity update(@NotNull TicketEntity ticketEntity) {
Transaction transaction = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
transaction = session.beginTransaction();
session.merge(ticketEntity);
transactionmit();
return ticketEntity;
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
throw e;
}
}
}
public class TicketService {
public @NotNull Optional<TicketEntity> addTask(@NotNull Integer ticketId, @NotNull TaskEntity task) {
return updateTicketEntity(ticketId, ticketEntity -> {
ticketEntity.addTask(task);
task.setTicket(ticketEntity);
});
}
private @NotNull Optional<TicketEntity> updateTicketEntity(@NotNull Integer ticketId, @NotNull Consumer<TicketEntity> updater) {
Optional<TicketEntity> entity = findById(ticketId);
return Preconditions.checkAndReturn(entity.isPresent(),
() -> {
TicketEntity ticketEntity = entity.get();
updater.accept(ticketEntity);
TicketEntity savedEntity = ticketRepository.update(ticketEntity);
ticketCache.put(ticketId, savedEntity);
return Optional.of(savedEntity);
},
Optional::empty);
}
}
So, when I add the TaskEntity value into TicketEntity tasks Collection and merging to database, then all the values that were in the tasks are saved, but with a new ID (11 - first saving, 12 - second). All that I need is saving the collection but without duplicates.
I have two entities:
@Setter
@Getter
@Entity
@Table(name = "Task")
@NoArgsConstructor
public class TaskEntity implements AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "mapName")
private String mapName;
@Column(name = "mapPath")
private String mapPath;
@Column(name = "mapCost")
private String mapCost;
@Column(name = "mapCostResult")
private String mapCostResult;
@Enumerated(EnumType.STRING)
@Column(name = "taskStatus")
private TaskStatus taskStatus;
@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "ticketId")
private TicketEntity ticket;
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(
name = "Builder_Task",
joinColumns = @JoinColumn(name = "taskId"),
inverseJoinColumns = @JoinColumn(name = "builderDiscordId")
)
private Set<BuilderEntity> builders = new HashSet<>();
public @NotNull TaskEntity addBuilder(@NotNull BuilderEntity builderEntity) {
builders.add(builderEntity);
return this;
}
public @NotNull TaskEntity removeBuilder(@NotNull BuilderEntity builderEntity) {
builders.remove(builderEntity);
return this;
}
}
and
@Setter
@Getter
@Entity
@Table(name = "Ticket")
@NoArgsConstructor
public class TicketEntity implements AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "channelId", unique = true)
private String channelId;
@Column(name = "creatorName")
private String creatorName;
@Column(name = "creationDate")
@CreationTimestamp
private Timestamp creationDate;
@Column(name = "deadline", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private Timestamp deadline;
@Column(name = "available")
private boolean available;
@Column(name = "mapsAmount")
private int mapsAmount;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true)
@OrderColumn(name = "ticketId")
private Set<TaskEntity> tasks = new HashSet<>();
public @NotNull TicketEntity addTask(@NotNull TaskEntity taskEntity) {
tasks.add(taskEntity);
return this;
}
public @NotNull TicketEntity removeTask(@NotNull TaskEntity taskEntity) {
tasks.remove(taskEntity);
return this;
}
}
Here are my service and repository:
public class TicketRepository implements CRUDRepository<TicketEntity, Integer> {
// Only needed function for question
@Override
public @NotNull TicketEntity update(@NotNull TicketEntity ticketEntity) {
Transaction transaction = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
transaction = session.beginTransaction();
session.merge(ticketEntity);
transactionmit();
return ticketEntity;
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
throw e;
}
}
}
public class TicketService {
public @NotNull Optional<TicketEntity> addTask(@NotNull Integer ticketId, @NotNull TaskEntity task) {
return updateTicketEntity(ticketId, ticketEntity -> {
ticketEntity.addTask(task);
task.setTicket(ticketEntity);
});
}
private @NotNull Optional<TicketEntity> updateTicketEntity(@NotNull Integer ticketId, @NotNull Consumer<TicketEntity> updater) {
Optional<TicketEntity> entity = findById(ticketId);
return Preconditions.checkAndReturn(entity.isPresent(),
() -> {
TicketEntity ticketEntity = entity.get();
updater.accept(ticketEntity);
TicketEntity savedEntity = ticketRepository.update(ticketEntity);
ticketCache.put(ticketId, savedEntity);
return Optional.of(savedEntity);
},
Optional::empty);
}
}
So, when I add the TaskEntity value into TicketEntity tasks Collection and merging to database, then all the values that were in the tasks are saved, but with a new ID (11 - first saving, 12 - second). All that I need is saving the collection but without duplicates.
Share Improve this question edited Nov 19, 2024 at 13:19 ahuemmer 2,05913 gold badges27 silver badges36 bronze badges asked Nov 19, 2024 at 9:56 GeoDGeoD 331 silver badge4 bronze badges1 Answer
Reset to default 0Finally, the problem was that I didn't add the task inside the transaction
public TicketEntity addTask(int ticketId, TaskEntity taskEntity) {
Transaction transaction = null;
TicketEntity ticketEntity = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
transaction = session.beginTransaction();
ticketEntity = session.get(TicketEntity.class, ticketId);
if (ticketEntity == null) {
throw new IllegalArgumentException("Ticket not found with ID: " + ticketId);
}
taskEntity.setTicket(ticketEntity);
ticketEntity.addTask(taskEntity);
session.merge(ticketEntity);
transactionmit();
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
}
return ticketEntity;
}
I have two entities:
@Setter
@Getter
@Entity
@Table(name = "Task")
@NoArgsConstructor
public class TaskEntity implements AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "mapName")
private String mapName;
@Column(name = "mapPath")
private String mapPath;
@Column(name = "mapCost")
private String mapCost;
@Column(name = "mapCostResult")
private String mapCostResult;
@Enumerated(EnumType.STRING)
@Column(name = "taskStatus")
private TaskStatus taskStatus;
@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "ticketId")
private TicketEntity ticket;
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(
name = "Builder_Task",
joinColumns = @JoinColumn(name = "taskId"),
inverseJoinColumns = @JoinColumn(name = "builderDiscordId")
)
private Set<BuilderEntity> builders = new HashSet<>();
public @NotNull TaskEntity addBuilder(@NotNull BuilderEntity builderEntity) {
builders.add(builderEntity);
return this;
}
public @NotNull TaskEntity removeBuilder(@NotNull BuilderEntity builderEntity) {
builders.remove(builderEntity);
return this;
}
}
and
@Setter
@Getter
@Entity
@Table(name = "Ticket")
@NoArgsConstructor
public class TicketEntity implements AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "channelId", unique = true)
private String channelId;
@Column(name = "creatorName")
private String creatorName;
@Column(name = "creationDate")
@CreationTimestamp
private Timestamp creationDate;
@Column(name = "deadline", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private Timestamp deadline;
@Column(name = "available")
private boolean available;
@Column(name = "mapsAmount")
private int mapsAmount;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true)
@OrderColumn(name = "ticketId")
private Set<TaskEntity> tasks = new HashSet<>();
public @NotNull TicketEntity addTask(@NotNull TaskEntity taskEntity) {
tasks.add(taskEntity);
return this;
}
public @NotNull TicketEntity removeTask(@NotNull TaskEntity taskEntity) {
tasks.remove(taskEntity);
return this;
}
}
Here are my service and repository:
public class TicketRepository implements CRUDRepository<TicketEntity, Integer> {
// Only needed function for question
@Override
public @NotNull TicketEntity update(@NotNull TicketEntity ticketEntity) {
Transaction transaction = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
transaction = session.beginTransaction();
session.merge(ticketEntity);
transactionmit();
return ticketEntity;
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
throw e;
}
}
}
public class TicketService {
public @NotNull Optional<TicketEntity> addTask(@NotNull Integer ticketId, @NotNull TaskEntity task) {
return updateTicketEntity(ticketId, ticketEntity -> {
ticketEntity.addTask(task);
task.setTicket(ticketEntity);
});
}
private @NotNull Optional<TicketEntity> updateTicketEntity(@NotNull Integer ticketId, @NotNull Consumer<TicketEntity> updater) {
Optional<TicketEntity> entity = findById(ticketId);
return Preconditions.checkAndReturn(entity.isPresent(),
() -> {
TicketEntity ticketEntity = entity.get();
updater.accept(ticketEntity);
TicketEntity savedEntity = ticketRepository.update(ticketEntity);
ticketCache.put(ticketId, savedEntity);
return Optional.of(savedEntity);
},
Optional::empty);
}
}
So, when I add the TaskEntity value into TicketEntity tasks Collection and merging to database, then all the values that were in the tasks are saved, but with a new ID (11 - first saving, 12 - second). All that I need is saving the collection but without duplicates.
I have two entities:
@Setter
@Getter
@Entity
@Table(name = "Task")
@NoArgsConstructor
public class TaskEntity implements AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "mapName")
private String mapName;
@Column(name = "mapPath")
private String mapPath;
@Column(name = "mapCost")
private String mapCost;
@Column(name = "mapCostResult")
private String mapCostResult;
@Enumerated(EnumType.STRING)
@Column(name = "taskStatus")
private TaskStatus taskStatus;
@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "ticketId")
private TicketEntity ticket;
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(
name = "Builder_Task",
joinColumns = @JoinColumn(name = "taskId"),
inverseJoinColumns = @JoinColumn(name = "builderDiscordId")
)
private Set<BuilderEntity> builders = new HashSet<>();
public @NotNull TaskEntity addBuilder(@NotNull BuilderEntity builderEntity) {
builders.add(builderEntity);
return this;
}
public @NotNull TaskEntity removeBuilder(@NotNull BuilderEntity builderEntity) {
builders.remove(builderEntity);
return this;
}
}
and
@Setter
@Getter
@Entity
@Table(name = "Ticket")
@NoArgsConstructor
public class TicketEntity implements AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "channelId", unique = true)
private String channelId;
@Column(name = "creatorName")
private String creatorName;
@Column(name = "creationDate")
@CreationTimestamp
private Timestamp creationDate;
@Column(name = "deadline", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private Timestamp deadline;
@Column(name = "available")
private boolean available;
@Column(name = "mapsAmount")
private int mapsAmount;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true)
@OrderColumn(name = "ticketId")
private Set<TaskEntity> tasks = new HashSet<>();
public @NotNull TicketEntity addTask(@NotNull TaskEntity taskEntity) {
tasks.add(taskEntity);
return this;
}
public @NotNull TicketEntity removeTask(@NotNull TaskEntity taskEntity) {
tasks.remove(taskEntity);
return this;
}
}
Here are my service and repository:
public class TicketRepository implements CRUDRepository<TicketEntity, Integer> {
// Only needed function for question
@Override
public @NotNull TicketEntity update(@NotNull TicketEntity ticketEntity) {
Transaction transaction = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
transaction = session.beginTransaction();
session.merge(ticketEntity);
transactionmit();
return ticketEntity;
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
throw e;
}
}
}
public class TicketService {
public @NotNull Optional<TicketEntity> addTask(@NotNull Integer ticketId, @NotNull TaskEntity task) {
return updateTicketEntity(ticketId, ticketEntity -> {
ticketEntity.addTask(task);
task.setTicket(ticketEntity);
});
}
private @NotNull Optional<TicketEntity> updateTicketEntity(@NotNull Integer ticketId, @NotNull Consumer<TicketEntity> updater) {
Optional<TicketEntity> entity = findById(ticketId);
return Preconditions.checkAndReturn(entity.isPresent(),
() -> {
TicketEntity ticketEntity = entity.get();
updater.accept(ticketEntity);
TicketEntity savedEntity = ticketRepository.update(ticketEntity);
ticketCache.put(ticketId, savedEntity);
return Optional.of(savedEntity);
},
Optional::empty);
}
}
So, when I add the TaskEntity value into TicketEntity tasks Collection and merging to database, then all the values that were in the tasks are saved, but with a new ID (11 - first saving, 12 - second). All that I need is saving the collection but without duplicates.
Share Improve this question edited Nov 19, 2024 at 13:19 ahuemmer 2,05913 gold badges27 silver badges36 bronze badges asked Nov 19, 2024 at 9:56 GeoDGeoD 331 silver badge4 bronze badges1 Answer
Reset to default 0Finally, the problem was that I didn't add the task inside the transaction
public TicketEntity addTask(int ticketId, TaskEntity taskEntity) {
Transaction transaction = null;
TicketEntity ticketEntity = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
transaction = session.beginTransaction();
ticketEntity = session.get(TicketEntity.class, ticketId);
if (ticketEntity == null) {
throw new IllegalArgumentException("Ticket not found with ID: " + ticketId);
}
taskEntity.setTicket(ticketEntity);
ticketEntity.addTask(taskEntity);
session.merge(ticketEntity);
transactionmit();
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
}
return ticketEntity;
}
本文标签: databaseJava Hibernate OneToMany collection problemStack Overflow
版权声明:本文标题:database - Java Hibernate. OneToMany collection problem - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745569135a2156630.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论