我使用JPA存储库将简单的数据对象保存到数据库中。为了避免重复,我在多个字段上创建了一个唯一约束。如果现在根据唯一字段/约束保存一个副本,我想捕获异常,记录对象,应用程序应继续并保存下一个对象。但在这里我总是会遇到这样的异常:“org.hibernate.AssertionFailure:de.test.PeopleDBO条目中的空id(在异常发生后不要刷新会话)”。
一般来说,我知道hibernate在做什么,但我知道如何恢复会话或启动新会话以继续保存下一个数据对象。请查看下面的代码:
PeopleDBO.java
@Entity
@Data
@Table(
name = "PEOPLE",
uniqueConstraints = {@UniqueConstraint(columnNames = {"firstname", "lastname"}})
public class PeopleDBO {
public PeopleDBO(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstname;
private String lastname;
}
测试:
public void should_save_people_and_ignore_constraint_violation(){
final List<PeopleDBO> peopleList = Arrays.asList(
new PeopleDBO("Georg","Smith"),
new PeopleDBO("Georg","Smith"),
new PeopleDBO("Paul","Smith")
);
peopleList.forEach(p -> {
try {
peopleRepository.save(p);
} catch (DataIntegrityViolationException e) {
log.error("Could not save due to constraint violation: {}",p);
}
}
Assertions.assertThat(peopleRepository.count()).isEqualTo(2);
}
问题是,随着第二个人的拯救,独特的约束被违反了。发生错误日志,并且随着peopleRepository.save()的下一次调用,将引发上面提到的异常:
"org.hibernate.AssertionFailure:de.test.PeopleDBO条目中的null id(发生异常后不刷新会话)"
我怎样才能避免这种行为?如何清理会话或启动新会话?
提前非常感谢d。
--------- 编辑/新想法 ------ 我只是尝试了一些东西,并看到我可以实现一个PeopleRepositoryImpl,如下所示:
@Service
public class PeopleRepositoryImpl {
final private PeopleRepository peopleRepository;
public PeopleRepositoryImpl(PeopleRepository peopleRepository) {
this.peopleRepository = peopleRepository;
}
@Transactional
public PeopleDBO save(PeopleDBO people){
return peopleRepository.save(people);
}
}
这在我的测试中效果很好。。。你怎么认为?
原因是所有插入都发生在一个事务中。由于这个事务是原子性的,它要么完全成功,要么失败,没有中间状态。
最干净的解决方案是在尝试插入一个People之前检查它是否存在:
public interface PeopleRespository {
boolean existsByLastnameAndFirstname(String lastname, String firstname);
}
然后:
if (!peopleRepository.existsByLastnameAndFirstname(p.getLastname, p.getFirstname)) {
peopleRepository.save(p);
}
一个替代方法是为每个人开始一个新的交易。但我不确定这样会更有效率,因为创建交易需要额外的成本。
我有以下课程: DBEntity.java 使用者JAVA 用户服务。JAVA UserRepository.java
我有一个数据已经保存在我的数据库基于我的存储库和服务。我想保存另一个数据与邮递员只改变播放器id。但它不是创建一个新的实体数据。它更新现有的实体数据。我的问题是如何更新一个数据由我的服务当它找到一个现有的id。但当它找到一个新的id将保存一个新的数据到数据库。 这是我的回购: 这是我的服务:
无论如何,如果用户名已经被使用,存储库只需进行更新,因为指定的标识符不是空的。这不是我想要的行为,我需要它抛出类似重复条目异常的东西。有什么办法可以预防吗?我必须自己做吗?例如:
我有下表,目前我可以更新用户对象来添加或删除角色,但我不能在创建新用户时向其添加角色(用户的角色添加到UI上的同一表单上),因为中间表User_Role希望用户的ID为Obj,所以在插入时,我自然得到一个User.user_id=?。 有什么常见的方法可以解决这个问题吗?我在考虑也许尝试在保存后获取插入用户的ID,然后调用更新函数。我不想这样做,因为我担心性能,特别是在未来可能发生批量上传的时候。
这很可能通过Nexus配置得到解决。 我们使用maven进行hadoop开发。Nexus被配置为所有存储库的镜像,存储库被添加到Nexus公共组中。(参见Nexus中有没有更好的配置存储库的方法?) 我发现hadoop-core工件版本1.0.4显示来自spring-roo-repositoryhttp://spring-roo-repository.springsource.org/releas
我正在尝试创建一个文字游戏,它可以对一个单词进行加密,并根据用户输入的内容将字符移位一定的数字,解密加密,并检查该单词是否为回文。问题是我不知道如何保持输入,所以在我加密或检查它是否为回文后,程序结束,因此我无法解密加密的内容。 例如,如果用户输入单词“hello”并选择加密该单词,密钥为3,则应显示“khoor”。然后,我希望能够通过将“khor”解密回“hello”来继续,但程序结束。 此外,