我目前正在使用Java开发一个task/project/tags Web应用程序,广泛使用Sping Boot JPA(我对这个框架相对较新,所以请原谅我)。我已经在Task和Tag实体之间声明了@ManyToMany关系(定义如下)。
任务实体:
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
@Entity()
@Table(name = "tasks_dim")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(updatable = false, nullable = false)
private Long id;
@Column(nullable = false)
private String name;
private String status;
private String priority;
@Column(name = "task_id_number", unique = true)
private String taskIdNumber;
@JsonIgnore
@ManyToOne(optional = false)
@JoinColumn(name = "user_id", referencedColumnName = "id")
private User user;
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.DETACH})
@JoinTable(name = "task_tags_dim",
joinColumns = @JoinColumn(name = "task_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id"))
private Set<Tag> tags = new LinkedHashSet<>();
@Temporal(TemporalType.DATE)
@Column(name = "due_date")
private Date dueDate;
public Task(String name, String status, String priority, User user) {
setName(name);
setDescription(description);
setStatus(status);
setPriority(priority);
setTaskIdNumber(new TaskIdNumberBuilder().buildTaskIdNumber());
setUser(user);
setDueDate(dueDate);
Timestamp currentTime = new Timestamp(new Date().getTime());
setCreatedOn(currentTime);
setLastUpdatedOn(currentTime);
}
字符串
标记实体:
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
@Entity()
@Table(name = "tags_dim")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(updatable = false, nullable = false)
private Long id;
@Column(nullable = false, unique = true)
private String name;
@ManyToMany(mappedBy = "tags", fetch = FetchType.LAZY)
private Set<Task> tasks = new LinkedHashSet<>();
public Tag(String name) {
setName(name);
}
型
但是,我的TagService类有问题,因为我无法在removeTag方法中使用getTags()。它返回一个空集合,所以即使我在create()和addTag()方法中添加标签,也没有什么可以删除的。如果我在create()中使用setTags(),我仍然无法从其他方法中的getTags()中获取任何数据。注意:
- create()创建一个新的Tag对象,在新创建的Tag对象和它各自的任务之间添加一个链接,并将其保存到数据库中
- addTag()在现有标记和给定的
- task removeTag()删除一个正在执行的标记和给定的
- task delete()删除所有标签(标签和任何任务之间的所有链接都应该被删除)
@Service
@Transactional
public class TagService {
@Autowired
private TagRepository tagRepository;
@Autowired
private TaskRepository taskRepository;
public Tag create(User user, Tag tag, Long task_id) {
try {
Optional<Task> optionalTask = taskRepository.findById(task_id);
if (optionalTask.isPresent()) {
Tag tagDetails = new Tag(tag.getName());
Tag savedTag = tagRepository.save(tagDetails);
Task currentTask = optionalTask.get();
currentTask.getTags().add(savedTag);
taskRepository.save(currentTask);
return savedTag;
}
} catch(IllegalArgumentException e) {
throw new IllegalArgumentException("Tag '" + tag.getName() + "' already exists.");
}
throw new NoSuchElementException("Task not found for the given task_id: " + task_id);
}
public Tag addTag(Tag tag, Long task_id) {
Optional<Task> optionalTask = taskRepository.findById(task_id);
if(optionalTask.isPresent()) {
Task task = optionalTask.get();
try {
task.getTags().add(tag);
taskRepository.save(task);
return tag;
} catch(Exception e) {
throw new IllegalArgumentException("Tag '" + tag.getName() + "' is a duplicate entry.");
}
}
throw new NoSuchElementException("Task not found for the given task_id: " + task_id);
}
public Set<Tag> getByTask(Long task_id) {
Optional<Task> optionalTask = taskRepository.findById(task_id);
if(optionalTask.isPresent()) {
Set<Tag> myTags = optionalTask.get().getTags();
for(Tag tag: myTags) {
System.out.println(tag.getName());
}
return tagRepository.findByTasks(optionalTask.get());
}
throw new IllegalArgumentException("Task not found for the given task_id: " + task_id);
}
public Set<Tag> removeTag(Tag tag, Long task_id) {
Optional<Task> optionalTask = taskRepository.findById(task_id);
try {
if(optionalTask.isPresent()) {
Task currentTask = optionalTask.get();
System.out.println(currentTask.getTags());
return currentTask.getTags();
}
} catch(IllegalArgumentException e) {
throw new IllegalArgumentException("Tag not found for the given task_id: " + task_id);
}
throw new NoSuchElementException("Request to remove tag from given task id '" + task_id + "' could not be processed");
}
public void delete(Tag tag) {
tagRepository.deleteById(tag);
}
}
型
我试过使用Hibernate.initialize,但没有成功。'FetchType.LAZY'是这个用例的理想类型吗?
1条答案
按热度按时间7dl7o3gd1#
可选解决方案1:在Task类中使用@Getter和@Setter而不是@Data。
可选解决方案2:
@Data
annotation中的@ToString
和@EqualsAndHashCode
annotation可能会导致问题。如果你想使用@Data
,你应该覆盖toString(),equals()和hashCode()方法。可选解决方案3:只需将
@EqualsAndHashCode(of = "id")
添加到Task类。