在最近的工作中,我使用spring-data- jpa来利用提供的存储库。在进行集成测试时,我无法配置(我假设)用于测试的Spring上下文,因此结果Bean验证在我的测试中不起作用。
我知道我可以注入验证器,并对注释进行单元测试,但事实并非如此。我正在编写集成测试,并且想测试具有数据库支持的存储库。
我准备了一个简单的项目来显示所有必要的项目文件。
当我运行测试时,2失败了,我也不知道为什么,类路径上出现了hibernate验证器。
Failed tests: insertWrongEmail(com.example.core.data.jpa.UserRepositoryTest): Expected ConstraintViolationException wasn't thrown. insertToShortPassword(com.example.core.data.jpa.UserRepositoryTest): Expected ConstraintViolationException wasn't thrown.
[..]
Apr 23, 2013 5:00:08 PM org.hibernate.validator.internal.util.Version <clinit> INFO: HV000001: Hibernate Validator 4.3.1.Final
源代码和 mvn测试 输出如下。
预先感谢您的帮助。
Java类(我去除了注释,获取器,设置器,等于,hashCode,toString等):
基础实体
package com.example.core.data.jpa; import javax.persistence.*; @MappedSuperclass public abstract class BaseEntity { public static final String SEQUENCE = "global_seq"; @Id @SequenceGenerator(name = SEQUENCE, sequenceName = SEQUENCE) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQUENCE) @Column(name = "id") private Long id; public Long getId() { return id; } }
用户
package com.example.core.data.jpa; import javax.persistence.*; import javax.validation.constraints.Pattern; import java.io.Serializable; import java.util.List; @Entity @Table(name = "users") @NamedQuery(name = "User.findByEmail", query = "select u from User u where upper(u.email) = :email") public class User extends BaseEntity implements Serializable { private static final long serialVersionUID = 333700989750828624L; private static final int MAX_NAME_LENGTH = 128; private static final int MAX_EMAIL_LENGTH = 128; private static final int MAX_PASSWORD_LENGTH = 256; private static final int MIN_NAME_LENGTH = 6; private static final int EQUALS_MAGIC = 71; @Size(min = MIN_NAME_LENGTH) @Column(name = "name", nullable = false, length = MAX_NAME_LENGTH) private String name; @Pattern(regexp = "^([0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\\.)+[a-zA-Z]{2,9})$") @Column(name = "email", nullable = false, unique = true, length = MAX_EMAIL_LENGTH) private String email; @Column(name = "password", nullable = false, length = MAX_PASSWORD_LENGTH) private String password; @OneToMany(mappedBy="user", cascade={CascadeType.ALL}, fetch = FetchType.EAGER) private List<Role> roles; //geters, seters, equals, hashCode }
角色
package com.example.core.data.jpa; import javax.persistence.*; import java.io.Serializable; @Entity @Table(name = "roles") public class Role extends BaseEntity implements Serializable { private static final long serialVersionUID = -2575871700366265974L; private static final int MAX_NAME_LENGTH = 128; @Column(name = "name", nullable = false, unique = true, length = MAX_NAME_LENGTH) private String name; @ManyToOne(cascade={CascadeType.ALL}) private User user; //geters, seters, equals, hashCode }
UserRepositoryTest
package com.example.core.data.jpa; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; import com.example.core.data.repository.UserRepository; import javax.inject.Inject; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; import static org.junit.Assert.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:test-context.xml") @Transactional public class UserRepositoryTest { @Inject private UserRepository userRepository; private User user; private static final String NAME = "User Name"; private static final String EMAIL = "user_name@example.com"; private static final String PASSWORD = "PASSWORD"; @Before public void setUp() { user = new User(NAME, EMAIL, PASSWORD); } @Test public void insert() { //given //when User inserted = userRepository.save(user); //then assertEquals(NAME, inserted.getName()); assertEquals(EMAIL, inserted.getEmail()); assertEquals(PASSWORD, inserted.getPassword()); assertNotNull(inserted.getId()); } @Test public void insertWrongEmail() { //given user.setEmail("NOT_AN_EMAIL_ADDRESS"); //when try { userRepository.save(user); fail("Expected ConstraintViolationException wasn't thrown."); } catch (ConstraintViolationException e) { //then assertEquals(1, e.getConstraintViolations().size()); ConstraintViolation<?> violation = e.getConstraintViolations().iterator().next(); assertEquals("email", violation.getPropertyPath().toString()); assertEquals(Pattern.class, violation.getConstraintDescriptor() .getAnnotation().annotationType()); } } @Test public void insertToShortName() { //given user.setName("SHORT"); //when try { userRepository.save(user); fail("Expected ConstraintViolationException wasn't thrown."); } catch (ConstraintViolationException e) { //then assertEquals(1, e.getConstraintViolations().size()); ConstraintViolation<?> violation = e.getConstraintViolations().iterator().next(); assertEquals("name", violation.getPropertyPath().toString()); assertEquals(Size.class, violation.getConstraintDescriptor() .getAnnotation().annotationType()); } } }
用户资料库
package com.example.core.data.repository; import org.springframework.data.repository.PagingAndSortingRepository; import com.example.core.data.jpa.User; public interface UserRepository extends PagingAndSortingRepository<User, Long> { }
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>data-jpa</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>Exampl core jpa package</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.hibernate.javax.persistence</groupId> <artifactId>hibernate-jpa-2.0-api</artifactId> <version>1.0.1.Final</version> </dependency> <dependency> <groupId>org.hibernate.java-persistence</groupId> <artifactId>jpa-api</artifactId> <version>2.0-cr-1</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.2.0.Final</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.0.0.GA</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.3.1.Final</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>1.6.0</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.12</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>1.2.0.RELEASE</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.2.2.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>2.2.9</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> </project>
test-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <context:annotation-config/> <jpa:repositories base-package="com.example.core.data.repository" /> <tx:annotation-driven transaction-manager="transactionManager" /> <jdbc:embedded-database id="dataSource" type="HSQL"/> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory" /> <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="packagesToScan"> <list> <value>com.example.core.data.jpa</value> </list> </property> </bean> <bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" p:generateDdl="true" p:database="HSQL" /> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" p:messageInterpolator-ref="messageInterpolator" p:validationMessageSource-ref="messageSource" /> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource" p:basename="classpath:I18N/messages,classpath:ValidationMessages*.properties" /> <bean id="messageInterpolator" class="org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator" /> </beans>
mvn测试 输出
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Example core jpa package 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ data-jpa --- [debug] execute contextualize [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ data-jpa --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ data-jpa --- [debug] execute contextualize [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] [INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ data-jpa --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.10:test (default-test) @ data-jpa --- [INFO] Surefire report directory: /home/[..]/data-jpa/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.example.core.data.jpa.UserRepositoryTest Apr 23, 2013 4:39:34 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [test-context.xml] Apr 23, 2013 4:39:35 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.GenericApplicationContext@3cd6ad74: startup date [Tue Apr 23 16:39:35 CEST 2013]; root of context hierarchy Apr 23, 2013 4:39:35 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init> INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring Apr 23, 2013 4:39:35 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization INFO: Bean 'org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver#423dc560' of type [class org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) Apr 23, 2013 4:39:35 PM org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory initDatabase INFO: Creating embedded database 'dataSource' Apr 23, 2013 4:39:35 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization INFO: Bean 'dataSource' of type [class org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) Apr 23, 2013 4:39:35 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization INFO: Bean 'dataSource' of type [class org.springframework.jdbc.datasource.SimpleDriverDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) Apr 23, 2013 4:39:35 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization INFO: Bean 'jpaAdapter' of type [class org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) Apr 23, 2013 4:39:35 PM org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean createNativeEntityManagerFactory INFO: Building JPA container EntityManagerFactory for persistence unit 'default' Apr 23, 2013 4:39:35 PM org.hibernate.annotations.common.Version <clinit> INFO: HCANN000001: Hibernate Commons Annotations {4.0.1.Final} Apr 23, 2013 4:39:35 PM org.hibernate.Version logVersion INFO: HHH000412: Hibernate Core {4.2.0.Final} Apr 23, 2013 4:39:35 PM org.hibernate.cfg.Environment <clinit> INFO: HHH000206: hibernate.properties not found Apr 23, 2013 4:39:35 PM org.hibernate.cfg.Environment buildBytecodeProvider INFO: HHH000021: Bytecode provider name : javassist Apr 23, 2013 4:39:35 PM org.hibernate.ejb.Ejb3Configuration configure INFO: HHH000204: Processing PersistenceUnitInfo [ name: default ...] Apr 23, 2013 4:39:36 PM org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator instantiateExplicitConnectionProvider INFO: HHH000130: Instantiating explicit connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider Apr 23, 2013 4:39:36 PM org.hibernate.dialect.Dialect <init> INFO: HHH000400: Using dialect: org.hibernate.dialect.HSQLDialect Apr 23, 2013 4:39:36 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory Apr 23, 2013 4:39:36 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init> INFO: HHH000397: Using ASTQueryTranslatorFactory Apr 23, 2013 4:39:36 PM org.hibernate.validator.internal.util.Version <clinit> INFO: HV000001: Hibernate Validator 4.3.1.Final Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute INFO: HHH000228: Running hbm2ddl schema update Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute INFO: HHH000102: Fetching database metadata Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute INFO: HHH000396: Updating schema Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata INFO: HHH000262: Table not found: roles Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata INFO: HHH000262: Table not found: users Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata INFO: HHH000262: Table not found: roles Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata INFO: HHH000262: Table not found: users Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata INFO: HHH000262: Table not found: global_seq Apr 23, 2013 4:39:37 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute INFO: HHH000232: Schema update complete Apr 23, 2013 4:39:37 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization INFO: Bean 'entityManagerFactory' of type [class org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) Apr 23, 2013 4:39:37 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization INFO: Bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0' of type [class org.springframework.transaction.annotation.AnnotationTransactionAttributeSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) Apr 23, 2013 4:39:37 PM org.springframework.context.support.AbstractApplicationContext$BeanPostProcessorChecker postProcessAfterInitialization INFO: Bean 'org.springframework.transaction.config.internalTransactionAdvisor' of type [class org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) Apr 23, 2013 4:39:37 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@69950b4: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,userRepository,org.springframework.data.repository.core.support.RepositoryInterfaceAwareBeanPostProcessor#0,org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,dataSource,transactionManager,entityManagerFactory,jpaAdapter,validator,messageSource,messageInterpolator,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener startNewTransaction INFO: Began transaction (1): transaction manager [org.springframework.orm.jpa.JpaTransactionManager@58eac93b]; rollback [true] Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction INFO: Rolled back transaction after test execution for test context [TestContext@2b98919b testClass = UserRepositoryTest, testInstance = com.example.core.data.jpa.UserRepositoryTest@2d7f6d79, testMethod = insert@UserRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@8ec3a45 testClass = UserRepositoryTest, locations = '{classpath:test-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]] Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener startNewTransaction INFO: Began transaction (2): transaction manager [org.springframework.orm.jpa.JpaTransactionManager@58eac93b]; rollback [true] Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction INFO: Rolled back transaction after test execution for test context [TestContext@2b98919b testClass = UserRepositoryTest, testInstance = com.example.core.data.jpa.UserRepositoryTest@1fcf7061, testMethod = insertWrongEmail@UserRepositoryTest, testException = java.lang.AssertionError: Expected ConstraintViolationException wasn't thrown., mergedContextConfiguration = [MergedContextConfiguration@8ec3a45 testClass = UserRepositoryTest, locations = '{classpath:test-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]] Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener startNewTransaction INFO: Began transaction (3): transaction manager [org.springframework.orm.jpa.JpaTransactionManager@58eac93b]; rollback [true] Apr 23, 2013 4:39:38 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction INFO: Rolled back transaction after test execution for test context [TestContext@2b98919b testClass = UserRepositoryTest, testInstance = com.example.core.data.jpa.UserRepositoryTest@168ee2a9, testMethod = insertToShortPassword@UserRepositoryTest, testException = java.lang.AssertionError: Expected ConstraintViolationException wasn't thrown., mergedContextConfiguration = [MergedContextConfiguration@8ec3a45 testClass = UserRepositoryTest, locations = '{classpath:test-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]] Tests run: 3, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 3.712 sec <<< FAILURE! Results : Failed tests: insertWrongEmail(com.example.core.data.jpa.UserRepositoryTest): Expected ConstraintViolationException wasn't thrown. insertToShortPassword(com.example.core.data.jpa.UserRepositoryTest): Expected ConstraintViolationException wasn't thrown. Tests run: 3, Failures: 2, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 6.216s [INFO] Finished at: Tue Apr 23 16:39:38 CEST 2013 [INFO] Final Memory: 7M/245M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.10:test (default-test) on project data-jpa: There are test failures. [ERROR] [ERROR] Please refer to /home/[..]/data-jpa/target/surefire-reports for the individual test results. [ERROR] -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException Process finished with exit code 1
解决了
从@gunnar回答后,我进行了更改测试,以在repository.save之后刷新持久性上下文,并且按预期工作。
对UserRepository的更改
//inject entity manager @PersistenceContext private EntityManager entityManager; //add flush after save in test method @Test public void insertWrongEmail() { //given user.setEmail("NOT_AN_EMAIL_ADDRESS"); //when try { userRepository.save(user); entityManager.flush(); fail("Expected ConstraintViolationException wasn't thrown.");
解决方案2
经过@andyb的推荐后,我已切换到eclipselink并进行了测试,而无需刷新。我认为这就是解决方案,切换实现比使用变通办法更好。
我设法在本地重现了该问题中确切描述的问题,尽管在将丢失的get / set函数和UserRepository该类添加回去之后:
UserRepository
经过一番挖掘后,我发现[与Bean ValidationAPI结合使用时,两个现存的问题JPAConstraintViolation vsRollback和Hibernate没有遵循JPA规范?
两者似乎都得出结论:Hibernate没有ConstraintValidationException正确抛出。
ConstraintValidationException
第二个问题的结果是一个缺陷HHH-8028-EntityManager.persist没有引发针对Hibernate的ConstraintValidationException。
为了确认这是相同的问题,我切换到简单@GeneratedValue并insertWrongEmail通过了。insertToShortPassword仍然失败,但我@Size(min=6)在密码字段中将其归结为丢失。添加之后,所有测试均通过。
@GeneratedValue
insertWrongEmail
insertToShortPassword
@Size(min=6)
回到您的配置@GeneratedValue,然后将Hibernate换成EclipseLink持久性框架。两项测试均通过,这似乎可以证实先前问题的发现。我所做的更改是:
pom.xml的 更改添加了EclipseLink网站上描述的jpa工件
<dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>org.eclipse.persistence.jpa</artifactId> <version>2.4.0</version> <scope>compile</scope> </dependency>
test-context.xml 更改
切换到 EclipseLinkJpaVendorAdapter
EclipseLinkJpaVendorAdapter
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter" p:generateDdl="true" p:database="HSQL" />
添加eclipselink.weaving属性,如EclipseLinkJpaVendorAdapter所述,而不是HibernateJpaVendorAdapter问题
eclipselink.weaving
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter" > <!-- existing configuration is identical --> <property name="jpaPropertyMap"> <map> <entry key="eclipselink.weaving" value="false"/> </map> </property> </bean>
User.java 更改
我需要添加一个默认的无参数构造函数。您可能已经在User.java全班学习了。
User.java