使用由JSF,Spring和Hibernate组成的应用程序.我的示例正常运行,然后当我将class ="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"更改为class ="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"时,应用程序没有正常运行.有什么问题?他们中的任何一个都是JPA的特殊要求.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.usta.spring" />
<tx:annotation-driven />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource" >
<!-- p:jpaVendorAdapter-ref="jpaAdapter"-->
<!-- <property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property> -->
<property name="jpaVendorAdapter" ref="jpaAdapter">
</property>
<property name="persistenceUnitName" value="Spring_PU"/>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost/spring"
p:username="root" p:password="root" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property …Run Code Online (Sandbox Code Playgroud) 对表单bean使用基于注释的验证时,对这些bean进行单元测试的最佳实践是什么,以确保为每个字段指定正确的验证注释?
例如,如果您有:
public class MyForm {
@NotNull
private String name;
}
Run Code Online (Sandbox Code Playgroud)
验证@NotNull应用于它的最佳方法是什么?
一个显而易见的方法是创建一个验证器,在它上面抛出一个null并期望它失败.但在我看来,这不是最好的方法,因为你将测试@NotNull使用它的行为和实现,而不是信任框架.
理想情况下,我希望使用反射或实用程序,使我可以断言某个@NotNull(和任何其他)验证应用于给定字段,而不必发送未通过验证的各种值组合.
这样做有一种优雅的方式,还是我一般都在正确的轨道上?
这个问题是对此问题的跟进:JPA ConstraintViolation vs Rollback
我做了一些关于JPA和验证API(JSR-303)组合的测试.
我在JPA规范中找到了以下内容(第101-102页):
默认情况下,默认Bean验证组(组默认值)将根据预先持久化和更新前的生命周期验证事件进行验证
...
如果validate方法返回的ConstraintViolation对象集不为空,则持久性提供程序必须抛出包含对返回的ConstraintViolation对象集的引用的javax.validation.ConstraintViolationException,并且必须将事务标记为回滚.
我设置了以下测试:
NameNotNullWithDefaultGeneratedStrategy具有使用默认策略(@Generated)和@NotNull String name列生成的id的实体NameNotNullWithTableGeneratedStrategy具有使用表策略(@TableGenerated)和@NotNull String name列生成的id的另一个实体persist使用null的每个实体的一个实例name.javax.validation.ConstraintViolationException由持久化方法抛出,并且事务标记为rollback only(即这些假设基于本文中引用的JPA规范).结果是:
persist方法javax.validation.ConstraintViolationException为两个实体抛出一个.rollback only在两种情况下都标记为persist抛出一个标记为的javax.validation.ConstraintViolationException实体NameNotNullWithDefaultGeneratedStrategy+事务rollback onlypersist不要将实体NameNotNullWithTableGeneratedStrategy+事务的任何异常都标记为rollback onlycommit对于NameNotNullWithTableGeneratedStrategy失败,并RollbackException问题是:
我想我刚刚发现两个不同的JPA实现在约束违规和回滚方面的工作方式不同.
@Test(expectedExceptions = @@.class) // CVE or RB?
public void testXXX() {
final EntityManager manager = LocalPU.createEntityManager();
try {
final EntityTransaction transaction = manager.getTransaction();
transaction.begin();
try {
manager.persist(<wrong>); // this is where CVE coming from
transaction.commit(); // this is where RB coming from
} catch (RollbackException re) {
// <---------------------------------------- hibernate here
throw re;
} catch (ConstraintViolationException cve) {
// <---------------------------------------- eclipselink here
transaction.rollback();
throw cve;
} catch (Exception e) {
transaction.rollback();
e.printStackTrace(System.err);
Assert.fail(e.getMessage());
}
} finally {
manager.close();
} …Run Code Online (Sandbox Code Playgroud) 在一个简单的项目中,我喜欢测试@NotNull验证(以及其他一些自定义验证).
因此我写了一些单元测试来执行这个: @Test(expect=ValidationException.class
一个最小的mavinized示例来重现我在github上传的问题:
mvn clean test我声称如果它@Id是一个生成的值,它运行良好.但如果@Id由系统给出,则忽略验证.
这个类将显示重现问题的最小设置:
这两个实体(一个具有生成值,一个没有h:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class GeneratedId {
@Id
@GeneratedValue
private Long id;
@NotNull
private String content;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class GivenId {
@Id
private Long id;
@NotNull
private String content;
}
Run Code Online (Sandbox Code Playgroud)
单元测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:/applicationContext.xml")
@Transactional
@ActiveProfiles("embedded")
public class MyEntityTest
{
@Autowired GeneratedIdService generatedIdService;
@Autowired GivenIdService givenIdService;
// This test will pass
@Test(expected = ValidationException.class)
public void shouldNotAllowNullValues1()
{ …Run Code Online (Sandbox Code Playgroud) java ×4
jpa ×4
hibernate ×3
eclipselink ×2
annotations ×1
lombok ×1
spring ×1
spring-data ×1
spring-mvc ×1
unit-testing ×1