文章是从网页上删除的,因此所有属性(如Medium
,Source
等)最初的ID都为NULL,并且其字段中包含已删除的数据。在保存文章之前,* toEntities() - 方法确保重用DB中已存在的数据。如果数据是新的,则通过Article
中的级联创建。</ p>
可能会删除重复的文章,这会在保存时抛出“非唯一的异常”,这很好,但之后其他文章仍应保存。我想我正在努力正确处理这个异常。解决方法是检查实体是否存在,但这会导致95%的时间不必要的工作。
在代码中,您看到了我的最后一次尝试,我试图在自己的事务中保存每篇文章,但我得到以下例外:
以下是ArticleService
的代码。如果你发现这堂课的其他错误,我也很高兴听到它们。
@Service
public class ArticleService {
@Autowired
private ArticleRepository articleRepository;
@Autowired
private CategoryRepository categoryRepository;
@Autowired
private SourcesRepository sourcesRepository;
@Autowired
private MediumRepository mediumRepository;
private final static Logger logger = LoggerFactory.getLogger("o.o.m.s.ArticleService");
@Transactional
public void save(Iterable<Article> articles) {
for (Article article : articles) {
save(article);
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(Article article) {
dataToEntities(article);
try {
articleRepository.save(article);
} catch (Exception e) {
e.printStackTrace();
}
}
@Transactional
public void delete(Iterable<Article> articles) {
if (articles == null) {
return;
}
for (Article article : articles) {
if (article.getId() != 0L) {
delete(article);
}
}
}
@Transactional
public void delete(Article article) {
article.setMedium(null);
article.setCategories(null);
article.setSources(null);
articleRepository.delete(article);
}
private void dataToEntities(Article article) {
categoriesToEntities(article);
sourcesToEntities(article);
mediumToEntity(article);
}
private void mediumToEntity(Article article) {
if (article.getMedium() == null) {
return;
}
Medium medium = mediumRepository.findByName(article.getMedium().getName());
if (medium != null) {
article.setMedium(medium);
}
}
private void sourcesToEntities(Article article) {
Set<Source> sources = new HashSet<>();
if (article.getSources() == null) {
return;
}
for (Source source : article.getSources()) {
Source entity = sourcesRepository.findByName(source.getName());
if (entity != null) {
sources.add(entity);
} else {
sources.add(source);
}
}
article.setSources(sources);
}
private void categoriesToEntities(Article article) {
Set<Category> categories = new HashSet<>();
if (article.getCategories() == null) {
return;
}
for (Category category : article.getCategories()) {
category = categoryRepository.findByName(category.getName());
categories.add(category);
}
article.setCategories(categories);
}
}
编辑:
我跟进了可能的重复问题并尝试了
NoRollBackFor-option,包含以下两种方法的所有可能异常:
@Transactional(propagation = Propagation.REQUIRES_NEW,noRollbackFor = {ConstraintViolationException.class,MySQLIntegrityConstraintViolationException.class,DataIntegrityViolationException.class,AssertionFailure.class,RollbackException.class})
这导致“TransactionSystemException:无法提交JPA事务;嵌套异常是javax.persistence.RollbackException:事务标记为rollbackOnly”。