Getting the identifier of the stored child in a one-to-many relationship

I have two entity classes A and B that look like this.

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;

}

Grade B:

public class B{

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

    @ManyToOne
    private A a;

    //Other class members;

}

I have a method that adds object B to object A. I want to return the identifier of the newly added object B.

eg:

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 list of B objects has the newly added bObject with it id. 
            // What is the best way to get its id?


}
+3
source share
4 answers

I have a method that adds object B to object A. I want to return the identifier of the newly added object B.

Then just do it! After a new instance of B has been saved (and the modified one is dumped to the database), it has idbeen assigned, just return it. Here is a test method that illustrates this behavior:

@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());
}

By the way, your code is a bit messy, you don't need commitafter every interaction with EM.

+2

, . . https://coderanch.com/t/628230/framework/Spring-Data-obtain-id-added

TL;DR; 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 todo.

    @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, imo, 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

, . , save org.hibernate.Session . / DAO, :

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

, - :

hibernateSession.persist(object); // persist returns void...
return object.getId(); // ... but you should have a getId method anyway
+1

- , -

@GeneratedValue(strategy = yourChosenStrategy)

by the identifier of the object that you save (or above its recipient). In this case, when persist is called, the identifier will be automatically set in the saved object.

Hope this helps!

0
source

Source: https://habr.com/ru/post/1758707/


All Articles