Bu soruya şuna bir iz gelir: JPA ConstraintViolation vs RollbackBean Validation API ile birleştirildiğinde, JPA spesifikasyonlarını takip etmiyor musunuz?
JPA ve doğrulama API'sinin (JSR-303) birleşimiyle ilgili bazı testler yaptım.
I (sayfa 101-102) JPA specifications aşağıdaki bulundu: Varsayılan olarak, varsayılan Bean Doğrulama grubu (grup Varsayılan) ön inat ve ön güncelleme yaşam döngüsü doğrulama üzerine doğrulanır ConstraintViolation kümesi validate yöntemi tarafından döndürülen nesnelerin ise olaylar
...
boş değil, kalıcılık sağlayıcısı ConstraintV döndürülen setine bir başvuru içeren javax.validation.ConstraintViolationException atmak gerekir iolation nesneleri ve geri alma işlemini işaretlemelidir.
ben kurulumun şöyle testi: olarak
- HibernateValidator JSR-303 uygulama
- 2 PersistenceProvider Hibernate ve EclipseLink
- bir varsayılan stratejisi (
@Generated
) ve@NotNull String name
ile üretilen bir kimliğe sahip varlıkNameNotNullWithDefaultGeneratedStrategy
Tablo stratejisiyle oluşturulan bir kimlikle - başka bir varlık
NameNotNullWithTableGeneratedStrategy
()) ve@NotNull String name
sütunu - testinde, null değerine sahip her varlığın bir örneğini
persist
deneyin. - beklenen sonuçlar, perspektif yöntemle atılan
javax.validation.ConstraintViolationException
verollback only
olarak işaretlenen işlemdir (yani, bu varsayımlar, bu yayında belirtilen JPA spesifikasyonuna dayanmaktadır).
sonuçlar şöyle:
- bir sağlayıcısı olarak tutulması bağlantı ile:
persist
yöntem hem kurumlara yönelikjavax.validation.ConstraintViolationException
atar.- işlem iki durumda sağlayıcısı olarak hazırda ile
- içinde
rollback only
olarak işaretlenmiş:persist
NameNotNullWithDefaultGeneratedStrategy
+ işlempersist
herhangi atmayınrollback only
olarak işaretlenmiş varlık içinjavax.validation.ConstraintViolationException
atar varlıkNameNotNullWithTableGeneratedStrategy
+ için işlem , işaretinirollback only
olarak işaretlemedi
- gerçekten JPA şartname ihlalidir:
NameNotNullWithTableGeneratedStrategy
için commit
soru vardır birRollbackException
ile başarısız? ya da tablonun oluşturduğu stratejinin özel durumuyla ilgili bir şey eksik miyim? Bir ihlali olması durumunda: İlgili herhangi bir hata raporu var mı?
package com.example.jpa.validator; import org.junit.Assert; import org.junit.Test; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; import javax.persistence.RollbackException; public class ConstraintViolationExceptionTest { @Test public void testHibernateDefaultStrategy() { // Success testPersistWithNullName("pu-hibernate",new NameNotNullWithDefaultGeneratedStrategy()); } @Test public void testHibernateTableStrategy() { testPersistWithNullName("pu-hibernate",new NameNotNullWithTableGeneratedStrategy()); //this test fail with : //java.lang.AssertionError: Expecting a javax.validation.ConstraintViolationException, but persist() succeed ! } @Test public void testEclipseLinkDefaultStrategy() { // Success testPersistWithNullName("pu-eclipselink",new NameNotNullWithDefaultGeneratedStrategy()); } @Test public void testEclipseLinkTableStrategy() { // Success testPersistWithNullName("pu-eclipselink",new NameNotNullWithTableGeneratedStrategy()); } private void testPersistWithNullName(String persistenceUnitName, Object entity){ EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnitName); EntityManager entityManager = emf.createEntityManager(); try { final EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); try { try { entityManager.persist(entity); Assert.fail("Expecting a javax.validation.ConstraintViolationException, but persist() succeed !"); } catch (javax.validation.ConstraintViolationException cve) { //That's expected Assert.assertTrue("According JPA specs transaction must be flagged as rollback only",transaction.getRollbackOnly()); } catch (Exception e) { Assert.assertTrue("According JPA specs transaction must be flagged as rollback only",transaction.getRollbackOnly()); e.printStackTrace(); Assert.fail("Expecting a javax.validation.ConstraintViolationException, but got " + e.getClass()); } transaction.commit(); Assert.fail("persisted with null name !!!"); } catch (RollbackException e) { //That's expected } catch (Exception e) { e.printStackTrace(); Assert.fail("Unexpected exception :"+e.getMessage()); } } finally { entityManager.close(); } } }
kişiler
Standart strateji
package com.example.jpa.validator; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.validation.constraints.NotNull; @Entity public class NameNotNullWithDefaultGeneratedStrategy { @Id @GeneratedValue private Long id; @NotNull public String name; public NameNotNullWithDefaultGeneratedStrategy() {} }
Tablo stategy:
İştepackage com.example.jpa.validator; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.TableGenerator; import javax.validation.constraints.NotNull; @Entity public class NameNotNullWithTableGeneratedStrategy { @GeneratedValue(strategy = GenerationType.TABLE, generator = "NAME_MUST_NOT_BE_NULL_ID_GENERATOR") @TableGenerator(name = "NAME_MUST_NOT_BE_NULL_ID_GENERATOR") @Id @NotNull private Long id; @NotNull public String name; public NameNotNullWithTableGeneratedStrategy() {} }
benim test için koddur
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="pu-hibernate" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.example.jpa.validator.NameNotNullWithTableGeneratedStrategy</class>
<class>com.example.jpa.validator.NameNotNullWithDefaultGeneratedStrategy</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test_mem_hibernate"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
</properties>
</persistence-unit>
<persistence-unit name="pu-eclipselink" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.example.jpa.validator.NameNotNullWithTableGeneratedStrategy</class>
<class>com.example.jpa.validator.NameNotNullWithDefaultGeneratedStrategy</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test_mem"/>
<property name="eclipselink.ddl-generation" value="create-tables"/>
<property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.H2Platform"/>
</properties>
</persistence-unit>
</persistence>
Bunun için bir hata raporu yayımlandı
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>com.example.jpa.validator</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<hibernate.version>4.2.0.CR1</hibernate.version>
<hibernate-validator.version>4.3.1.Final</hibernate-validator.version>
<junit.version>4.11</junit.version>
<h2.version>1.3.170</h2.version>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
<repositories>
<repository>
<url>http://download.eclipse.org/rt/eclipselink/maven.repo/</url>
<id>eclipselink</id>
<layout>default</layout>
<name>Repository for library EclipseLink (JPA 2.0)</name>
</repository>
</repositories>
</project>
@column (ne yapılmaktadır = false null) @NotNull ile birlikte mi? –
'@Column (nullable = false)' ile denedim: aynı sonuç – ben75
Gerçekten de neden üretim stratejisinin bu durumda doğrulamayı etkilediğini anlamıyorum, ancak bir test raporunu zaten yaptığınız gibi bir hata raporunu kesinlikle açacağım hazırda bekletme bölümünün ardından hazırda bekletme-validator'a karşı. –