Blokowanie metody @Transactional

0

Siemka. Mam problem z dodaniem niektórych obiektów do bazy danych. Mam obiekt użytkownika, który zawiera obiekt @OneToOne, który jest skrzynką wiodomości. Istnieje w niej obiekt Set <Conversation> zawierający listę rozmów. Rozmowa zawiera informacje o sobie i liście obiektów List<Message>. Wiadomość zawiera kilka innych danych. Zrobiłem metodę oznaczoną jako @Transactional, która "tworzy nową wiadomość". Wykonuję w nim odpowiednie operacje, a następnie zapisuję dane w powyższych obiektach. Robię to w ten sposób:

@Transactional
public Set<Conversation> newMessage(MessageHelper messageHelper) {
    User sender = userRepository.getUserByUserName(messageHelper.getFrom());
    User receiver = userRepository.getUserByUserName(messageHelper.getTo());

    Conversation senderConversation = conversationRepository.getConversationWithUser(sender.getUsername(), receiver.getUsername());
    if(senderConversation == null)
        senderConversation = new Conversation(sender.getUsername(), receiver.getUsername());

    Conversation receiverConversation = conversationRepository.getConversationWithUser(receiver.getUsername(), sender.getUsername());
    if(receiverConversation == null)
        receiverConversation = new Conversation(receiver.getUsername(), sender.getUsername());

    Message message = messageHelper.getMessage();
    receiverConversation.getMessages().add(message);

    Message receiverMessage = new Message(message.getMessageFrom(), message.getMessage());
    receiverMessage.setWhenSent(message.getWhenSent());
    senderConversation.getMessages().add(receiverMessage);

    sender.getMessageBox().getConversationList().add(senderConversation);
    receiver.getMessageBox().getConversationList().add(receiverConversation);

    entityManager.persist(message);
    entityManager.persist(receiverMessage);

    entityManager.merge(sender);
    entityManager.merge(receiver);


    Set<Conversation> conversations = getConversations(sender.getUsername());
    System.out.println("Conv from service: " + conversations);
    System.out.println(userRepository.getUserByUserName(sender.getUsername()));
    // the application hangs here
    return conversations;
}

Następnie chcę zwrócić konwersacje użytkownika po utworzeniu, aby zawierał aktualne dane po stronie klienta. Wszystko wydaje się być w porządku, wypisując w konsoli dane o konwersacji i użytkowniku jest wszystko ok, są również wszystkie id, nie są nullami, ale obiekt nie jest zwracany, a metoda zawiesza się i nie zwraca niczego bez rzucania wyjątku. Aplikacja kliencka oczekuje na odpowiedź z serwera, ale nic się nie dzieje, aplikacja serwera zawiesza się. Co ja robię źle?

0

NIe widze dlaczego się ma zawieszać, może powód jest na zewnątrz tego kodu, gdzie wywołujesz. To Spring i JPA? Dużo rzeczy może się wyrypać.
Ale najbardziej nie rozumiem po co:

    entityManager.merge(sender);
    entityManager.merge(receiver);

Co ten kawałek kodu miał zrobić?

0

Ogólnie myśl jest taka że wiadomość ląduje do skrzynki odbiorcy i nadawcy więc aktualizuje dane obu. Co do technologii to Spring Boot + Jpa. Jeśli chodzi o wywoływanie to raczej standardowo. Na Resta przychodzi obiekt, jest normalnie odczytywany itp. Dane po wykonaniu metod entityManager'a też wyświetlam żeby się upewnić i są ok. Sam właśnie nie wiem co może być nie tak.

Jak coś to dodaje logi od insertów z trybu debugowania:

2018-09-28 13:47:58.447 DEBUG 10476 --- [nio-8090-exec-1] org.hibernate.SQL                        : insert into message (is_readed, message, message_from, when_sent, id) values (?, ?, ?, ?, ?)
2018-09-28 13:47:58.449 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIT] - [false]
2018-09-28 13:47:58.450 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [VARCHAR] - [aaaaaaa]
2018-09-28 13:47:58.450 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [3] as [VARCHAR] - [mati]
2018-09-28 13:47:58.451 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [4] as [TIMESTAMP] - [Fri Sep 28 13:47:57 CEST 2018]
2018-09-28 13:47:58.452 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [5] as [BIGINT] - [785]
2018-09-28 13:47:58.454 DEBUG 10476 --- [nio-8090-exec-1] org.hibernate.SQL                        : insert into message (is_readed, message, message_from, when_sent, id) values (?, ?, ?, ?, ?)
2018-09-28 13:47:58.455 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIT] - [false]
2018-09-28 13:47:58.455 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [VARCHAR] - [aaaaaaa]
2018-09-28 13:47:58.455 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [3] as [VARCHAR] - [mati]
2018-09-28 13:47:58.455 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [4] as [TIMESTAMP] - [Fri Sep 28 13:47:57 CEST 2018]
2018-09-28 13:47:58.455 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [5] as [BIGINT] - [786]
2018-09-28 13:47:58.467 DEBUG 10476 --- [nio-8090-exec-1] org.hibernate.SQL                        : insert into message_box_conversation_list (message_box_id, conversation_list_id) values (?, ?)
2018-09-28 13:47:58.467 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [674]
2018-09-28 13:47:58.467 TRACE 10476 --- [nio-8090-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [BIGINT] - [721]

Nie powiem, że jestem orłem w tych technologiach bo wprawdzie dopiero zaczynam ale na moje oko to tak wygląda jakby dane były dodane "wstępnie" ale cała transakcja nie została zakończona i jest przez coś blokowana.

0

Nadal nie wyjaśniłes po co te dwie linijki.

Jak transakcja wisi - touzyj narzędzi odpowiednich do twojej bazy danych i sprawdź na czym wisi.

0

Dodałem po to by pobrane wcześniej obiekty zaktualizować.
Apropos to Set<Conversation> i List<Message> są oparte na @ElementCollection jakby coś.

0

I sądziesz, że te wywołania (u Ciebie) coś aktualizują? Masz to z jakiejś książki czy coś?
Edit: nie sprawdziłeś w bazie na czym to wisi?
Mozesz dodac przed retutn jeszcze entityManager.flush() jak sie na tym zawiesi, to mniej wiecej wiadomo, że masz blokade na bazie.

0

Pomijając tego merga, to @Transactional skąd masz?

0

Nie sądzę i nie mam szczerze mówiąc :D Jedynie wcześniej robiąc podobne rzeczy w ten sposób dawało to wymierne korzyści więc tutaj też tak zrobiłem. Ogólnie to jak wcześniej pisałem orłem w tym nie jestem więc mogę nie wiedzieć dokładnie jak coś działa.

@yarel
Początkowo z javax.transaction.Transactional potem org.springframework.transaction.annotation.Transactional ale efekt ten sam.

0

Hmmm nie wiem jak ale uruchomiłem od nowa laptopa (pewnie przy okazji się baza danych uruchomiła na nowo) i wszystko działa :D
W każdym razie dziękuje Wam za pomoc :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1