Ok, sprawa wygląda tak: Wczoraj jednak nie próbowałem z Cascade.ALL, ale próbowałem z hibernate-ową adnotacją @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE), nie zauważyłem zmian. Gdy ustawię CascadeType.ALL, wtedy save w ogóle nie commituje zmian do bazy danych, co więcej przy drugim insercie wyrzuca wyjątek
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "article_statuses",
joinColumns = @JoinColumn(name = "article_id", nullable = false),
inverseJoinColumns = @JoinColumn(name = "status_id", nullable = false))
private Set<ArticleStatus> statuses = new HashSet<>();
Wyjątek:
org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.drcloak.articles.status.ArticleStatus#1]
@CountZero używam w taki sposób:
Tworzenie sesji:
@Configuration
public class HibernateConfig {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Bean
public Session getSession() {
return entityManagerFactory.createEntityManager().unwrap(Session.class);
}
}
Service:
@Service
@Transactional
public class NewArticleService {
private final ArticleStatusRepository articleStatusRepository;
private final ArticleRepository articleRepository;
private final UserHelperService userHelperService;
@Autowired
public NewArticleService(ArticleRepository articleRepository, ArticleStatusRepository articleStatusRepository,
UserHelperService userHelperService) {
this.articleRepository = articleRepository;
this.articleStatusRepository = articleStatusRepository;
this.userHelperService = userHelperService;
}
public void createArticle(NewArticleDto newArticleDto) {
User currentUser = userHelperService.getCurrentUser();
ArticleStatus articleStatus = articleStatusRepository.findByName(NEW)
.orElseThrow(() -> new InternalServerErrorException("Article Status not set."));
Article article = new Article(newArticleDto.title, newArticleDto.summary, newArticleDto.content, currentUser);
article.setStatuses(Collections.singleton(articleStatus));
articleRepository.createArticle(article);
}
}
Repository:
@Repository
@Transactional
public class ArticleRepository {
private final Session session;
@Autowired
public ArticleRepository(Session session) {
this.session = session;
}
public void createArticle(Article article) {
session.save(article);
}
(...)
Edit:
z kaskadą Persist nie tworzą się articles :(
Edit2:
Zmieniłem sposób tworzenia sesji, zaczęło działać bez żadnej kaskady. Mógłby mi ktoś wytłumaczyć różnicę? I dlaczego działa nawet bez kaskady?
@Repository
@Transactional
public class ArticleRepository {
@PersistenceContext
private EntityManager entityManager;
public void createArticle(Article article) {
getSession().save(article);
}
private Session getSession() {
return entityManager.unwrap(Session.class);
}
}