我有两个实体类A和B,如下所示。
public class A{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(mappedBy = "a", fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
private List<B> blist = new ArrayList<B>();
//Other class members;
}
B组:
public class B{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
private A a;
//Other class members;
}
我有一个将B对象添加到A对象的方法。我想返回新添加的B对象的id。
例如:
public Long addBtoA(long aID){
EntityTransaction tx = myDAO.getEntityManagerTransaction();
tx.begin();
A aObject = myDAO.load(aID);
tx.commit();
B bObject = new B();
bObject.addB(bObject);
tx.begin();
myDAO.save(aObject);
tx.commit();
//Here I want to return the ID of the saved bObject.
// After saving aObject it's list of B objects has the newly added bObject with it's id.
// What is the best way to get its id?
}
答案 0 :(得分:2)
我有一个将B对象添加到A对象的方法。我想返回新添加的B对象的id。
然后就这样做!在保留新B实例(并将更改刷新到数据库)之后,已分配其id
,只需返回它。以下是一种说明此行为的测试方法:
@Test
public void test_Add_B_To_A() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyPu");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
A a = em.find(A.class, 1L);
B b = new B();
A.addToBs(b); // convenient method that manages the bidirectional association
em.getTransaction().commit(); // pending changes are flushed
em.close();
emf.close();
assertNotNull(b.getId());
}
顺便说一句,你的代码有点混乱,每次与EM交互后你都不需要commit
。
答案 1 :(得分:2)
我认为接受的答案是正确的。见https://coderanch.com/t/628230/framework/Spring-Data-obtain-id-added
tldr;
您应该只为子项B
创建一个存储库,这样您就可以完全独立于父项保存子项。获得保存后的B entity
,然后将其与其父A
相关联。
以下是一些示例代码,其中Todo
为父级,Comment
为子级。
@Entity
public class Todo {
@OneToMany(mappedBy = "todo", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<Comment> comments = new HashSet<>();
// getters/setters omitted.
}
@Entity
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
@JoinColumn(name = "todo_id")
private Todo todo;
// getters/setters omitted.
}
如果这是在spring数据中建模的,则创建2个存储库。 TodoRepository
和CommentRepository
Autowired
in。
给定一个休息端点能够接收POST /api/todos/1/comments
以将新评论与给定的待办事项ID相关联。
@PostMapping(value = "/api/todos/{todoId}/comments")
public ResponseEntity<Resource<Comment>> comments(@PathVariable("todoId") Long todoId,
@RequestBody Comment comment) {
Todo todo = todoRepository.findOne(todoId);
// SAVE the comment first so its filled with the id from the DB.
Comment savedComment = commentRepository.save(comment);
// Associate the saved comment to the parent Todo.
todo.addComment(savedComment);
// Will update the comment with todo id FK.
todoRepository.save(todo);
// return payload...
}
如果您执行了以下操作,则保存提供的参数comment
。获取新评论的唯一方法是遍历todo.getComments()
并查找提供的comment
,如果该集合是Set
,则会感到烦人且不切实际。
@PostMapping(value = "/api/todos/{todoId}/comments")
public ResponseEntity<Resource<Comment>> comments(@PathVariable("todoId") Long todoId,
@RequestBody Comment comment) {
Todo todo = todoRepository.findOne(todoId);
// Associate the supplied comment to the parent Todo.
todo.addComment(comment);
// Save the todo which will cascade the save into the child
// Comment table providing cascade on the parent is set
// to persist or all etc.
Todo savedTodo = todoRepository.save(todo);
// You cant do comment.getId
// Hibernate creates a copy of comment and persists it or something.
// The only way to get the new id is iterate through
// todo.getComments() and find the matching comment which is
// impractical especially if the collection is a set.
// return payload...
}
答案 2 :(得分:1)
您应首先保留新创建的对象,然后将其添加到其容器中。另外,save
的{{1}}方法返回新持久对象的标识符。所以你只需更新你的代码和/或你的DAO就像这样:
org.hibernate.Session
无论如何,对于具有生成ID的所有对象,您始终可以执行以下操作:
newObject.setContainer(container); // facultative (only if the underlying SGBD forbids null references to the container)
Long id = (Long) hibernateSession.save(newObject); // assuming your identifier is a Long
container.add(newObject);
// now, id contains the id of your new object
答案 3 :(得分:0)
如果有人在以前的评论中找不到解决方案,另一个选择是添加
@GeneratedValue(strategy = yourChosenStrategy)
覆盖您持久存在的实体的ID(或其获取者的ID)。在这种情况下,当调用persist时,id将自动设置在持久化对象中。
希望它有所帮助!