Question

I ont deux classes d'entités A et B qui se présente comme suit.

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;

}

Classe B:

public class B{

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

    @ManyToOne
    private A a;

    //Other class members;

}

I ont un procédé qui ajoute un objet B à un objet A. Je veux retourner l'identifiant du nouveau ajouté objet B.

par exemple:

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?


}
Était-ce utile?

La solution

  

I ont un procédé qui ajoute un objet B à un objet A. Je veux retourner l'identifiant du nouveau ajouté objet B.

Alors faites-le! Après la nouvelle instance B a été persisté (et changé rincée à la base de données), son id a été attribué, il suffit de retourner. Voici une méthode d'essai qui illustre ce comportement:

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

Par ailleurs, votre code est un désordre de peu, vous ne avez pas besoin de commit après chaque interaction avec l'EM.

Autres conseils

Je ne pense pas que la réponse acceptée est correcte. Voir https://coderanch.com/t/628230/framework / Spring-Data-Obtain ajoutée id-

tldr; Vous devez simplement créer un référentiel pour le B de l'enfant afin que vous puissiez sauver l'enfant tout à fait indépendamment de son parent. Une fois que vous avez le B entity ensuite enregistré l'associer à sa A mère.

Voici quelques exemples de code avec Todo étant le parent et l'enfant étant 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.
}

Si cela a été modélisé dans les données de printemps, vous créez 2 référentiels. TodoRepository et CommentRepository qui sont en Autowired.

Étant donné un point de terminaison reste capable de recevoir POST /api/todos/1/comments pour associer un nouveau commentaire avec un id todo donné.

    @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...
    }

Si au contraire, vous avez fait le ci-dessous et enregistré le comment paramètre fourni. La seule façon d'obtenir le nouveau commentaire itérer est par todo.getComments() et trouver le comment qui est fourni imo ennuyeux et peu pratique si la collection est un 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...
    }

Vous devriez persisteront votre objet nouvellement créé d'abord, puis l'ajouter à son récipient. Additionnellement, le procédé de save de org.hibernate.Session renvoie l'identifiant d'un objet nouvellement persisté. Donc, il vous suffit de mettre à jour votre code et / ou votre DAO à se comporter comme ceci:

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

Quoi qu'il en soit, pour tous les objets avec ids générés, vous pouvez toujours faire quelque chose comme ceci:

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

Dans le cas où quelqu'un ne trouve pas de solution sur les commentaires précédents, une autre option est d'ajouter

@GeneratedValue(strategy = yourChosenStrategy)

sur l'ID de l'entité que vous persistez (ou par son getter). Dans ce cas, lorsque l'on appelle persist, l'identifiant sera automatiquement définie dans l'objet persistait.

it helps!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top