我有以下JPA实体
@Entity
class UserEntity {
companion object {
fun fromParameters(uuid: String, email: String, password: String, firstName: String, lastName: String) =
UserEntity().apply {
this.uuid = uuid
this.email = email
this.password = password
this.firstName = firstName
this.lastName = lastName
}
}
@Id
lateinit var uuid: String
@Column(nullable = false, unique = true)
lateinit var email: String
@Column(nullable = false)
lateinit var password: String
@Column(nullable = false)
lateinit var firstName: String
@Column(nullable = false)
lateinit var lastName: String
}
这是我的测试,用于检查UNIQUE约束,并使用相同的电子邮件插入另一个用户。
@RunWith(SpringRunner::class)
@DataJpaTest
@AutoConfigureTestEntityManager
class TestUserCrudRepository {
@Autowired
private lateinit var userCrudRepository: UserCrudRepository
private val testUserEntity = UserEntity.fromParameters(
UUID.randomUUID().toString(),
"test@test.com",
"password".toHash(),
"Caetano",
"Veloso"
)
@Test
fun `when email already exists it should throw error`() {
with (userCrudRepository) {
save(testUserEntity)
val newUserEntity = with (testUserEntity) { UserEntity.fromParameters(UUID.randomUUID().toString(), email, password, firstName, lastName) }
shouldThrow<SQLException> { save(newUserEntity) }
}
}
}
新实体总是插入重复的电子邮件,不会引发任何异常。
Expected exception java.sql.SQLException but no exception was thrown
我在日志中看到该表已根据给定的约束正确创建。
Hibernate: drop table user_entity if exists
Hibernate: create table user_entity (uuid varchar(255) not null, email varchar(255) not null, first_name varchar(255) not null, last_name varchar(255) not null, password varchar(255) not null, primary key (uuid))
Hibernate: alter table user_entity add constraint UK_4xad1enskw4j1t2866f7sodrx unique (email)
谢谢!
答案 0 :(得分:2)
发生这种情况是因为没有发布$parts = explode("]", $content);
$i=0;
while (isset($solution[$i])){
//answer correct
if($solution[$i] == $input[$i]){
//replace placeholder > green solution
$parts[$i] = str_replace("[".$solution[$i], "[".$solution_green[$i], $parts[$i]);
}
//answer wrong
else{
//replace placeholder > input box to try again
$parts[$i] = str_replace("[".$solution[$i], "[".$solution_box[$i], $parts[$i]);
}
$i++;
}
$content = implode( "]", $parts);
语句。
Hibernate不会insert
会话,除非有充分的理由这样做。
@DataJpaTest
是@Transactional
。这意味着在其中执行的flush
方法返回的事务将在该方法返回后回滚。@Test
映射还鼓励休眠模式延迟UserEntity
(尝试在insert
属性上使用@GeneratedValue(strategy = IDENTITY)
来强制发出id
s)不深入细节,运行测试时会发生以下情况:
insert
的交易begin
方法运行@Test
-Hibernate意识到没有理由访问数据库并延迟 save(testUserEntity)
insert
-与以前的shouldThrow<SQLException> { save(newUserEntity) }
方法返回@Test
,因为没有理由。最简单的方法是使用JpaRepository#flush
:
insert
请注意,CrudRepository
中没有with (userCrudRepository) {
save(testUserEntity)
val newUserEntity = with (testUserEntity) { UserEntity.fromParameters(UUID.randomUUID().toString(), email, password, firstName, lastName) }
save(newUserEntity)
assertThrows<DataIntegrityViolationException> {
flush()
}
}
方法
我想您已经扩展了flush
...您可能想扩展CrudRepository
。
请参阅:What is difference between CrudRepository and JpaRepository interfaces in Spring Data JPA?
关于异常的说明
您期望抛出SQLException
。
但是请注意,将改为抛出DataIntegrityViolationException
。