mirror of
https://github.com/apache/openjpa.git
synced 2025-02-22 01:55:29 +00:00
OPENJPA-1082 Added support for configurable bean validation groups
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@791678 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8597b330e5
commit
5283bcd77d
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.openjpa.integration.validation;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class DefGrpEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
// NotNull constraint with default validation group
|
||||||
|
@NotNull
|
||||||
|
private String dgName;
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDgName(String dgName) {
|
||||||
|
this.dgName = dgName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDgName() {
|
||||||
|
return dgName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.openjpa.integration.validation;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class MixedGrpEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String defNotNull;
|
||||||
|
|
||||||
|
@NotNull(groups=ValGroup1.class)
|
||||||
|
private String vg1NotNull;
|
||||||
|
|
||||||
|
@NotNull(groups=ValGroup2.class)
|
||||||
|
private String vg2NotNull;
|
||||||
|
|
||||||
|
@NotNull(groups={ValGroup1.class, ValGroup2.class})
|
||||||
|
private String vg12NotNull;
|
||||||
|
|
||||||
|
public void setDefNotNull(String defNotNull) {
|
||||||
|
this.defNotNull = defNotNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefNotNull() {
|
||||||
|
return defNotNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVg1NotNull(String vg1NotNull) {
|
||||||
|
this.vg1NotNull = vg1NotNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVg1NotNull() {
|
||||||
|
return vg1NotNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVg2NotNull(String vg2NotNull) {
|
||||||
|
this.vg2NotNull = vg2NotNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVg2NotNull() {
|
||||||
|
return vg2NotNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVg12NotNull(String vg12NotNull) {
|
||||||
|
this.vg12NotNull = vg12NotNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVg12NotNull() {
|
||||||
|
return vg12NotNull;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.openjpa.integration.validation;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import org.apache.openjpa.integration.validation.ValGroup1;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class NonDefGrpEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
// NotNull constraint with default validation group
|
||||||
|
@NotNull
|
||||||
|
private String dgName;
|
||||||
|
|
||||||
|
// NotNull constraint with specified validation group
|
||||||
|
@NotNull(groups=ValGroup1.class)
|
||||||
|
private String ndgName;
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDgName(String dgName) {
|
||||||
|
this.dgName = dgName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDgName() {
|
||||||
|
return dgName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNdgName(String dgName) {
|
||||||
|
this.ndgName = dgName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNdgName() {
|
||||||
|
return ndgName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,639 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.openjpa.integration.validation;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
|
import javax.validation.ConstraintViolationException;
|
||||||
|
|
||||||
|
import org.apache.openjpa.lib.log.Log;
|
||||||
|
import org.apache.openjpa.persistence.OpenJPAEntityManager;
|
||||||
|
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
|
||||||
|
import org.apache.openjpa.persistence.OpenJPAPersistence;
|
||||||
|
import org.apache.openjpa.persistence.test.PersistenceTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the Bean Validation groups support as defined in the JPA 2.0 spec
|
||||||
|
* via the following scenarios:
|
||||||
|
*
|
||||||
|
* Verify default validation group on lifecycle events:
|
||||||
|
* 1a) PrePersist and PreUpdate validate with default validation group
|
||||||
|
* 1b) PreRemove does not validate with default validation group
|
||||||
|
* 1c) Specify the default group for PreRemove and verify that it validates with
|
||||||
|
* the default group.
|
||||||
|
* 1d) Verify validation for constraints using non-default validation groups
|
||||||
|
* does not occur.
|
||||||
|
*
|
||||||
|
* Verify validation occurs when specific validation groups are specified:
|
||||||
|
* 2a) Specify a non-default group for all lifecycle events.
|
||||||
|
* 2b) Specify multiple/mixed non-default groups for lifecycle events.
|
||||||
|
*
|
||||||
|
* Verify validation does not occur when no validation groups are specified:
|
||||||
|
* 3a) Specify an empty validation group for PrePersist and PreUpdate and
|
||||||
|
* verify validation does not occur on these events.
|
||||||
|
*
|
||||||
|
* @version $Rev$ $Date$
|
||||||
|
*/
|
||||||
|
public class TestValidationGroups extends PersistenceTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1a) verify validation occurs using the default validation groups
|
||||||
|
* on pre-persist and pre-update on commit
|
||||||
|
*/
|
||||||
|
public void testDefaultValidationGroup() {
|
||||||
|
verifyDefaultValidationGroup(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1af) verify validation occurs using the default validation groups
|
||||||
|
* on pre-persist and pre-update on flush
|
||||||
|
*/
|
||||||
|
public void testDefaultValidationGroupFlush() {
|
||||||
|
verifyDefaultValidationGroup(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1b) verify validation does not occur using the default validation group
|
||||||
|
* on the PreRemove lifecycle event on commit.
|
||||||
|
*/
|
||||||
|
public void testDefaultPreRemove() {
|
||||||
|
verifyDefaultPreRemove(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1bf) verify validation does not occur using the default validation group
|
||||||
|
* on the PreRemove lifecycle event on flush.
|
||||||
|
*/
|
||||||
|
public void testDefaultPreRemoveFlush() {
|
||||||
|
verifyDefaultPreRemove(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1c) verify validation occurs on the default group when default is
|
||||||
|
* specified for pre-remove on commit
|
||||||
|
*/
|
||||||
|
public void testSpecifiedDefaultPreRemove() {
|
||||||
|
verifySpecifiedDefaultPreRemove(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1cf) verify validation occurs on the default group when default is
|
||||||
|
* specified for pre-remove on flush
|
||||||
|
*/
|
||||||
|
public void testSpecifiedDefaultPreRemoveFlush() {
|
||||||
|
verifySpecifiedDefaultPreRemove(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2a) verify non-default validation group for all lifecycle events on
|
||||||
|
* commit. default validation group constraints should not validate
|
||||||
|
*/
|
||||||
|
public void testNonDefaultValidationGroup() {
|
||||||
|
verifyNonDefaultValidationGroup(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2af) verify non-default validation group for all lifecycle events on
|
||||||
|
* flush. default validation group constraints should not validate
|
||||||
|
*/
|
||||||
|
public void testNonDefaultValidationGroupFlush() {
|
||||||
|
verifyNonDefaultValidationGroup(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2b) verify multiple/mixed validation groups
|
||||||
|
* @param flush
|
||||||
|
*/
|
||||||
|
public void testMultipleValidationGroups() {
|
||||||
|
|
||||||
|
// Configure persistence properties via map
|
||||||
|
Map<String, Object> propMap = new HashMap<String, Object>();
|
||||||
|
propMap.put("javax.persistence.validation.group.pre-persist",
|
||||||
|
"org.apache.openjpa.integration.validation.ValGroup1," +
|
||||||
|
"org.apache.openjpa.integration.validation.ValGroup2");
|
||||||
|
|
||||||
|
propMap.put("javax.persistence.validation.group.pre-update",
|
||||||
|
"");
|
||||||
|
|
||||||
|
propMap.put("javax.persistence.validation.group.pre-remove",
|
||||||
|
"org.apache.openjpa.integration.validation.ValGroup2");
|
||||||
|
|
||||||
|
OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
|
||||||
|
OpenJPAPersistence.createEntityManagerFactory(
|
||||||
|
"multi-validation-group",
|
||||||
|
"org/apache/openjpa/integration/validation/persistence.xml",
|
||||||
|
propMap);
|
||||||
|
assertNotNull(emf);
|
||||||
|
// create EM
|
||||||
|
OpenJPAEntityManager em = emf.createEntityManager();
|
||||||
|
assertNotNull(em);
|
||||||
|
|
||||||
|
try {
|
||||||
|
MixedGrpEntity mge = new MixedGrpEntity();
|
||||||
|
|
||||||
|
// Assert vg1 and vg2 fire on pre-persist
|
||||||
|
try
|
||||||
|
{
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist(mge);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
checkCVE(e,
|
||||||
|
"vg1NotNull",
|
||||||
|
"vg2NotNull",
|
||||||
|
"vg12NotNull");
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Should have caught a ConstraintViolationException");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (em.getTransaction().isActive()) {
|
||||||
|
em.getTransaction().rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Assert no validation occurs on pre-update
|
||||||
|
// Persist an entity. Default should not validate on pre-persist
|
||||||
|
em.getTransaction().begin();
|
||||||
|
mge.setVg1NotNull("Vg1");
|
||||||
|
mge.setVg2NotNull("Vg2");
|
||||||
|
mge.setVg12NotNull("Vg1&2");
|
||||||
|
em.persist(mge);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
em.getTransaction().begin();
|
||||||
|
mge.setDefNotNull(null);
|
||||||
|
mge.setVg12NotNull(null);
|
||||||
|
mge.setVg1NotNull(null);
|
||||||
|
mge.setVg2NotNull(null);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
fail("Update should have been successful." +
|
||||||
|
" Caught unexpected ConstraintViolationException.");
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Update should have been successful." +
|
||||||
|
" Caught unexpected exception.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the entity again so that it can be cleaned up by the
|
||||||
|
// emf cleanup facility. The update should not validate
|
||||||
|
em.getTransaction().begin();
|
||||||
|
mge.setVg2NotNull("Vg2NotNull");
|
||||||
|
mge.setVg12NotNull("Vg12NotNull");
|
||||||
|
em.getTransaction().commit();
|
||||||
|
|
||||||
|
// Assert vg2 and default groups validate on pre-remove
|
||||||
|
try {
|
||||||
|
em.getTransaction().begin();
|
||||||
|
mge.setDefNotNull(null);
|
||||||
|
mge.setVg1NotNull(null);
|
||||||
|
mge.setVg2NotNull(null);
|
||||||
|
mge.setVg12NotNull(null);
|
||||||
|
em.remove(mge);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
checkCVE(e,
|
||||||
|
"vg2NotNull",
|
||||||
|
"vg12NotNull");
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Should have caught a ConstraintViolationException");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (em.getTransaction().isActive()) {
|
||||||
|
em.getTransaction().rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
cleanup(emf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 3a) No validation groups for pre-persist and pre-update and none for
|
||||||
|
* pre-remove by default. No validation should occur.
|
||||||
|
*/
|
||||||
|
public void testNoValidationGroups() {
|
||||||
|
|
||||||
|
// Configure persistence properties via map
|
||||||
|
Map<String, Object> propMap = new HashMap<String, Object>();
|
||||||
|
propMap.put("javax.persistence.validation.group.pre-persist","");
|
||||||
|
|
||||||
|
propMap.put("javax.persistence.validation.group.pre-update","");
|
||||||
|
|
||||||
|
OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
|
||||||
|
OpenJPAPersistence.createEntityManagerFactory(
|
||||||
|
"multi-validation-group",
|
||||||
|
"org/apache/openjpa/integration/validation/persistence.xml",
|
||||||
|
propMap);
|
||||||
|
assertNotNull(emf);
|
||||||
|
// create EM
|
||||||
|
OpenJPAEntityManager em = emf.createEntityManager();
|
||||||
|
assertNotNull(em);
|
||||||
|
|
||||||
|
try {
|
||||||
|
MixedGrpEntity mge = new MixedGrpEntity();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// No validation on pre-persist
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist(mge);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
|
||||||
|
// No validation on pre-update
|
||||||
|
em.getTransaction().begin();
|
||||||
|
mge.setVg12NotNull(null);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
|
||||||
|
// No validation on pre-remove
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.remove(mge);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
fail("Operations should have been successful." +
|
||||||
|
" Caught unexpected ConstraintViolationException.");
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Operations should have been successful." +
|
||||||
|
" Caught unexpected exception.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
cleanup(emf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyDefaultValidationGroup(boolean flush) {
|
||||||
|
OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
|
||||||
|
OpenJPAPersistence.createEntityManagerFactory(
|
||||||
|
"default-validation-group",
|
||||||
|
"org/apache/openjpa/integration/validation/persistence.xml");
|
||||||
|
assertNotNull(emf);
|
||||||
|
// create EM
|
||||||
|
OpenJPAEntityManager em = emf.createEntityManager();
|
||||||
|
assertNotNull(em);
|
||||||
|
try {
|
||||||
|
DefGrpEntity dge = new DefGrpEntity();
|
||||||
|
// Test pre-persist with default group with flush after persist
|
||||||
|
// 1a) pre-persist
|
||||||
|
try {
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist(dge);
|
||||||
|
if (flush)
|
||||||
|
em.flush();
|
||||||
|
else
|
||||||
|
em.getTransaction().commit();
|
||||||
|
fail("A ConstraintViolationException should have been thrown " +
|
||||||
|
"on pre-persist");
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
checkCVE(e, "dgName");
|
||||||
|
// If flushing, tx should be marked for rollback
|
||||||
|
if (flush) {
|
||||||
|
assertTrue(em.getTransaction().isActive());
|
||||||
|
assertTrue(em.getTransaction().getRollbackOnly());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Should have caught a ConstraintViolationException");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (em.getTransaction().isActive()) {
|
||||||
|
em.getTransaction().rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1a) test pre-update with default group
|
||||||
|
// Add an entity with valid data (validation passes)
|
||||||
|
dge.setDgName("NonNullName");
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist(dge);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
try {
|
||||||
|
// Update the entity with null value. pre-update
|
||||||
|
// validation should fail on flush or commit
|
||||||
|
em.getTransaction().begin();
|
||||||
|
dge.setDgName(null);
|
||||||
|
if (flush)
|
||||||
|
em.flush();
|
||||||
|
else
|
||||||
|
em.getTransaction().commit();
|
||||||
|
fail("A ConstraintViolationException should have been thrown " +
|
||||||
|
"on pre-update");
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
checkCVE(e, "dgName");
|
||||||
|
// If flushing, tx should be marked for rollback
|
||||||
|
if (flush) {
|
||||||
|
assertTrue(em.getTransaction().isActive());
|
||||||
|
assertTrue(em.getTransaction().getRollbackOnly());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Should have caught a ConstraintViolationException");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (em.getTransaction().isActive()) {
|
||||||
|
em.getTransaction().rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
cleanup(emf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyNonDefaultValidationGroup(boolean flush) {
|
||||||
|
OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
|
||||||
|
OpenJPAPersistence.createEntityManagerFactory(
|
||||||
|
"non-default-validation-group",
|
||||||
|
"org/apache/openjpa/integration/validation/persistence.xml");
|
||||||
|
assertNotNull(emf);
|
||||||
|
// create EM
|
||||||
|
OpenJPAEntityManager em = emf.createEntityManager();
|
||||||
|
assertNotNull(em);
|
||||||
|
try {
|
||||||
|
NonDefGrpEntity ndge = new NonDefGrpEntity();
|
||||||
|
// Test pre-persist with non-default group with flush after persist
|
||||||
|
try {
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist(ndge);
|
||||||
|
if (flush)
|
||||||
|
em.flush();
|
||||||
|
else
|
||||||
|
em.getTransaction().commit();
|
||||||
|
fail("A ConstraintViolationException should have been thrown " +
|
||||||
|
"on pre-persist");
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
checkCVE(e, "ndgName");
|
||||||
|
getLog(emf).trace("Caught expected exception");
|
||||||
|
// If flushing, tx should be marked for rollback
|
||||||
|
if (flush) {
|
||||||
|
assertTrue(em.getTransaction().isActive());
|
||||||
|
assertTrue(em.getTransaction().getRollbackOnly());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Should have caught a ConstraintViolationException");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (em.getTransaction().isActive()) {
|
||||||
|
em.getTransaction().rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pre-update with non-default group. default group
|
||||||
|
// validation should not occur
|
||||||
|
// Add an entity with valid data (validation passes)
|
||||||
|
try {
|
||||||
|
ndge.setNdgName("NonNullName");
|
||||||
|
ndge.setDgName(null);
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist(ndge);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
getLog(emf).trace("Entity was persisted. As expected, no " +
|
||||||
|
"validation took place on pre-persist with default group.");
|
||||||
|
}
|
||||||
|
catch (ConstraintViolationException e) {
|
||||||
|
fail("Caught unexpected exception");
|
||||||
|
if (em.getTransaction().isActive())
|
||||||
|
em.getTransaction().rollback();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// Update the entity with null value. pre-update
|
||||||
|
// validation should fail on flush or commit
|
||||||
|
|
||||||
|
em.getTransaction().begin();
|
||||||
|
ndge.setNdgName(null);
|
||||||
|
if (flush)
|
||||||
|
em.flush();
|
||||||
|
else
|
||||||
|
em.getTransaction().commit();
|
||||||
|
fail("A ConstraintViolationException should have been thrown " +
|
||||||
|
"on pre-update");
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
checkCVE(e, "ndgName");
|
||||||
|
// If flushing, tx should be marked for rollback
|
||||||
|
if (flush) {
|
||||||
|
assertTrue(em.getTransaction().isActive());
|
||||||
|
assertTrue(em.getTransaction().getRollbackOnly());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Should have caught a ConstraintViolationException");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (em.getTransaction().isActive()) {
|
||||||
|
em.getTransaction().rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge the entity so that it can be removed.
|
||||||
|
em.getTransaction().begin();
|
||||||
|
ndge.setDgName(null);
|
||||||
|
ndge.setNdgName("Some name");
|
||||||
|
ndge = em.merge(ndge);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Update the entity with null value and remove the entity.
|
||||||
|
// validation should not fail on pre-remove
|
||||||
|
em.getTransaction().begin();
|
||||||
|
ndge.setNdgName(null);
|
||||||
|
em.remove(ndge);
|
||||||
|
if (flush)
|
||||||
|
em.flush();
|
||||||
|
else
|
||||||
|
em.getTransaction().commit();
|
||||||
|
fail("A ConstraintViolationException should have been thrown " +
|
||||||
|
"on pre-remove");
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
checkCVE(e, "ndgName");
|
||||||
|
// If flushing, tx should be marked for rollback
|
||||||
|
if (flush) {
|
||||||
|
assertTrue(em.getTransaction().isActive());
|
||||||
|
assertTrue(em.getTransaction().getRollbackOnly());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Should have caught a ConstraintViolationException");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
cleanup(emf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* verify validation does not occur using the default validation group
|
||||||
|
* on the PreRemove lifecycle event.
|
||||||
|
*/
|
||||||
|
public void verifyDefaultPreRemove(boolean flush) {
|
||||||
|
OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
|
||||||
|
OpenJPAPersistence.createEntityManagerFactory(
|
||||||
|
"default-validation-group",
|
||||||
|
"org/apache/openjpa/integration/validation/persistence.xml");
|
||||||
|
assertNotNull(emf);
|
||||||
|
// create EM
|
||||||
|
OpenJPAEntityManager em = emf.createEntityManager();
|
||||||
|
assertNotNull(em);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Add an entity
|
||||||
|
DefGrpEntity dge = new DefGrpEntity();
|
||||||
|
dge.setDgName("NonNullName");
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist(dge);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
try {
|
||||||
|
// Update the entity with null value and remove the entity.
|
||||||
|
// validation should not fail on pre-remove
|
||||||
|
em.getTransaction().begin();
|
||||||
|
dge.setDgName(null);
|
||||||
|
em.remove(dge);
|
||||||
|
if (flush)
|
||||||
|
em.flush();
|
||||||
|
else
|
||||||
|
em.getTransaction().commit();
|
||||||
|
getLog(emf).trace("Entity was removed. As expected, no " +
|
||||||
|
"validation took place on pre-remove.");
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
fail("Should not have caught a ConstraintViolationException");
|
||||||
|
getLog(emf).trace("Caught expected exception");
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Should not have caught an Exception");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (em.getTransaction().isActive()) {
|
||||||
|
em.getTransaction().rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
cleanup(emf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* verify validation occurs when the default validation group
|
||||||
|
* is specified for the PreRemove lifecycle event via the
|
||||||
|
* "javax.persistence.validation.group.pre-remove" property.
|
||||||
|
*/
|
||||||
|
public void verifySpecifiedDefaultPreRemove(boolean flush) {
|
||||||
|
OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
|
||||||
|
OpenJPAPersistence.createEntityManagerFactory(
|
||||||
|
"pre-remove-default-validation-group",
|
||||||
|
"org/apache/openjpa/integration/validation/persistence.xml");
|
||||||
|
assertNotNull(emf);
|
||||||
|
// create EM
|
||||||
|
OpenJPAEntityManager em = emf.createEntityManager();
|
||||||
|
assertNotNull(em);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Add an entity
|
||||||
|
DefGrpEntity dge = new DefGrpEntity();
|
||||||
|
dge.setDgName("NonNullName");
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist(dge);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
try {
|
||||||
|
// Update the entity with null value and remove the entity.
|
||||||
|
// validation should not fail on pre-remove
|
||||||
|
em.getTransaction().begin();
|
||||||
|
dge.setDgName(null);
|
||||||
|
em.remove(dge);
|
||||||
|
if (flush)
|
||||||
|
em.flush();
|
||||||
|
else
|
||||||
|
em.getTransaction().commit();
|
||||||
|
fail("A ConstraintViolationException should have been thrown " +
|
||||||
|
"on pre-remove");
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
checkCVE(e, "dgName");
|
||||||
|
// If flushing, tx should be marked for rollback
|
||||||
|
if (flush) {
|
||||||
|
assertTrue(em.getTransaction().isActive());
|
||||||
|
assertTrue(em.getTransaction().getRollbackOnly());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
fail("Should have caught a ConstraintViolationException");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (em.getTransaction().isActive()) {
|
||||||
|
em.getTransaction().rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
cleanup(emf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCVE(ConstraintViolationException e,
|
||||||
|
String... vioProperties) {
|
||||||
|
Set<?>cvs = e.getConstraintViolations();
|
||||||
|
if (vioProperties.length == 0 && cvs == null)
|
||||||
|
return;
|
||||||
|
assertEquals(vioProperties.length, cvs.size());
|
||||||
|
Iterator<ConstraintViolation<?>> i =
|
||||||
|
(Iterator<ConstraintViolation<?>>) cvs.iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
ConstraintViolation<?> v = (ConstraintViolation<?>)i.next();
|
||||||
|
boolean found = false;
|
||||||
|
for (String vio : vioProperties) {
|
||||||
|
if (v.getPropertyPath().equals(vio)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
fail("Unexpected ConstraintViolation for: " +
|
||||||
|
v.getPropertyPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove entities and close the emf an any open em's.
|
||||||
|
* @param emf
|
||||||
|
*/
|
||||||
|
private void cleanup(OpenJPAEntityManagerFactorySPI emf) {
|
||||||
|
clear(emf);
|
||||||
|
closeEMF(emf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal convenience method for getting the OpenJPA logger
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Log getLog(OpenJPAEntityManagerFactorySPI emf) {
|
||||||
|
return emf.getConfiguration().getLog("Tests");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.openjpa.integration.validation;
|
||||||
|
|
||||||
|
public interface ValGroup1 {
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.openjpa.integration.validation;
|
||||||
|
|
||||||
|
public interface ValGroup2 {
|
||||||
|
}
|
@ -69,5 +69,50 @@
|
|||||||
<class>org.apache.openjpa.integration.validation.ConstraintNull</class>
|
<class>org.apache.openjpa.integration.validation.ConstraintNull</class>
|
||||||
<validation-mode>CALLBACK</validation-mode>
|
<validation-mode>CALLBACK</validation-mode>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
|
|
||||||
|
<persistence-unit name="default-validation-group">
|
||||||
|
<class>org.apache.openjpa.integration.validation.DefGrpEntity</class>
|
||||||
|
<validation-mode>CALLBACK</validation-mode>
|
||||||
|
<properties>
|
||||||
|
<property name="openjpa.jdbc.SynchronizeMappings"
|
||||||
|
value="buildSchema"/>
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
|
||||||
|
<persistence-unit name="pre-remove-default-validation-group">
|
||||||
|
<class>org.apache.openjpa.integration.validation.DefGrpEntity</class>
|
||||||
|
<validation-mode>CALLBACK</validation-mode>
|
||||||
|
<properties>
|
||||||
|
<property name="openjpa.jdbc.SynchronizeMappings"
|
||||||
|
value="buildSchema"/>
|
||||||
|
<property name="javax.persistence.validation.group.pre-remove"
|
||||||
|
value="javax.validation.groups.Default"/>
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
|
||||||
|
<persistence-unit name="non-default-validation-group">
|
||||||
|
<class>org.apache.openjpa.integration.validation.NonDefGrpEntity</class>
|
||||||
|
<validation-mode>CALLBACK</validation-mode>
|
||||||
|
<properties>
|
||||||
|
<property name="openjpa.jdbc.SynchronizeMappings"
|
||||||
|
value="buildSchema"/>
|
||||||
|
<property name="javax.persistence.validation.group.pre-persist"
|
||||||
|
value="org.apache.openjpa.integration.validation.ValGroup1"/>
|
||||||
|
<property name="javax.persistence.validation.group.pre-update"
|
||||||
|
value="org.apache.openjpa.integration.validation.ValGroup1"/>
|
||||||
|
<property name="javax.persistence.validation.group.pre-remove"
|
||||||
|
value="org.apache.openjpa.integration.validation.ValGroup1"/>
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
|
||||||
|
<persistence-unit name="multi-validation-group">
|
||||||
|
<class>org.apache.openjpa.integration.validation.MixedGrpEntity</class>
|
||||||
|
<validation-mode>CALLBACK</validation-mode>
|
||||||
|
<properties>
|
||||||
|
<property name="openjpa.jdbc.SynchronizeMappings"
|
||||||
|
value="buildSchema"/>
|
||||||
|
<!-- Properties passed in via createEMF -->
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
|
||||||
</persistence>
|
</persistence>
|
||||||
|
@ -1773,4 +1773,46 @@ public interface OpenJPAConfiguration
|
|||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
public void setWriteBehindCallback(String wbcallback);
|
public void setWriteBehindCallback(String wbcallback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the validation groups for pre-persist
|
||||||
|
*
|
||||||
|
* @Since 2.0.0
|
||||||
|
*/
|
||||||
|
public String getValidationGroupPrePersist();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the validation groups for pre-persist
|
||||||
|
*
|
||||||
|
* @Since 2.0.0
|
||||||
|
*/
|
||||||
|
public void setValidationGroupPrePersist(String vgPrePersist);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the validation groups for pre-update
|
||||||
|
*
|
||||||
|
* @Since 2.0.0
|
||||||
|
*/
|
||||||
|
public String getValidationGroupPreUpdate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the validation groups for pre-update
|
||||||
|
*
|
||||||
|
* @Since 2.0.0
|
||||||
|
*/
|
||||||
|
public void setValidationGroupPreUpdate(String vgPreUpdate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the validation groups for pre-remove
|
||||||
|
*
|
||||||
|
* @Since 2.0.0
|
||||||
|
*/
|
||||||
|
public String getValidationGroupPreRemove();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the validation groups for pre-remove
|
||||||
|
*
|
||||||
|
* @Since 2.0.0
|
||||||
|
*/
|
||||||
|
public void setValidationGroupPreRemove(String vgPreRemove);
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,9 @@ public class OpenJPAConfigurationImpl
|
|||||||
public ObjectValue validationFactory;
|
public ObjectValue validationFactory;
|
||||||
public ObjectValue validator;
|
public ObjectValue validator;
|
||||||
public ObjectValue lifecycleEventManager;
|
public ObjectValue lifecycleEventManager;
|
||||||
|
public StringValue validationGroupPrePersist;
|
||||||
|
public StringValue validationGroupPreUpdate;
|
||||||
|
public StringValue validationGroupPreRemove;
|
||||||
public ObjectValue writeBehindCachePlugin;
|
public ObjectValue writeBehindCachePlugin;
|
||||||
public ObjectValue writeBehindCacheManagerPlugin;
|
public ObjectValue writeBehindCacheManagerPlugin;
|
||||||
public ObjectValue writeBehindCallbackPlugin;
|
public ObjectValue writeBehindCallbackPlugin;
|
||||||
@ -574,6 +576,24 @@ public class OpenJPAConfigurationImpl
|
|||||||
validationMode = addString("javax.persistence.validation.mode");
|
validationMode = addString("javax.persistence.validation.mode");
|
||||||
validationMode.setDynamic(true);
|
validationMode.setDynamic(true);
|
||||||
|
|
||||||
|
String defValidationGroup = "javax.validation.groups.Default";
|
||||||
|
validationGroupPrePersist =
|
||||||
|
addString("javax.persistence.validation.group.pre-persist");
|
||||||
|
validationGroupPrePersist.setString(defValidationGroup);
|
||||||
|
validationGroupPrePersist.setDefault("");
|
||||||
|
validationGroupPrePersist.setDynamic(true);
|
||||||
|
|
||||||
|
validationGroupPreUpdate =
|
||||||
|
addString("javax.persistence.validation.group.pre-update");
|
||||||
|
validationGroupPreUpdate.setString(defValidationGroup);
|
||||||
|
validationGroupPreUpdate.setDefault("");
|
||||||
|
validationGroupPreUpdate.setDynamic(true);
|
||||||
|
|
||||||
|
validationGroupPreRemove =
|
||||||
|
addString("javax.persistence.validation.group.pre-remove");
|
||||||
|
validationGroupPreRemove.setDefault("");
|
||||||
|
validationGroupPreRemove.setDynamic(true);
|
||||||
|
|
||||||
validationFactory = addObject("javax.persistence.validation.factory");
|
validationFactory = addObject("javax.persistence.validation.factory");
|
||||||
validationFactory.setInstantiatingGetter(
|
validationFactory.setInstantiatingGetter(
|
||||||
"getValidationFactoryInstance");
|
"getValidationFactoryInstance");
|
||||||
@ -1592,6 +1612,39 @@ public class OpenJPAConfigurationImpl
|
|||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setValidationGroupPrePersist(String vgPrePersist) {
|
||||||
|
validationGroupPrePersist.setString(vgPrePersist);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValidationGroupPrePersist() {
|
||||||
|
String vgPrePersist = validationGroupPrePersist.getString();
|
||||||
|
if (vgPrePersist == null)
|
||||||
|
vgPrePersist = validationGroupPrePersist.getDefault();
|
||||||
|
return vgPrePersist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValidationGroupPreUpdate(String vgPreUpdate) {
|
||||||
|
validationGroupPreUpdate.setString(vgPreUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValidationGroupPreUpdate() {
|
||||||
|
String vgPreUpdate = validationGroupPreUpdate.getString();
|
||||||
|
if (vgPreUpdate == null)
|
||||||
|
vgPreUpdate = validationGroupPreUpdate.getDefault();
|
||||||
|
return vgPreUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValidationGroupPreRemove(String vgPreRemove) {
|
||||||
|
validationGroupPreRemove.setString(vgPreRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValidationGroupPreRemove() {
|
||||||
|
String vgPreRemove = validationGroupPreRemove.getString();
|
||||||
|
if (vgPreRemove == null)
|
||||||
|
vgPreRemove = validationGroupPreRemove.getDefault();
|
||||||
|
return vgPreRemove;
|
||||||
|
}
|
||||||
|
|
||||||
public void instantiateAll() {
|
public void instantiateAll() {
|
||||||
super.instantiateAll();
|
super.instantiateAll();
|
||||||
getMetaDataRepositoryInstance();
|
getMetaDataRepositoryInstance();
|
||||||
|
@ -97,9 +97,7 @@ public class ValidationUtils {
|
|||||||
// we have the javax.validation APIs
|
// we have the javax.validation APIs
|
||||||
try {
|
try {
|
||||||
// try loading a validation provider
|
// try loading a validation provider
|
||||||
ValidatorImpl validator = new ValidatorImpl(
|
ValidatorImpl validator = new ValidatorImpl(conf);
|
||||||
conf.getValidationFactoryInstance(),
|
|
||||||
conf.getValidationMode());
|
|
||||||
// set the Validator into the config
|
// set the Validator into the config
|
||||||
conf.setValidatorInstance(validator);
|
conf.setValidatorInstance(validator);
|
||||||
// update the LifecycleEventManager plugin to use it
|
// update the LifecycleEventManager plugin to use it
|
||||||
|
@ -30,7 +30,9 @@ import javax.validation.Validation;
|
|||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
import javax.validation.ValidatorFactory;
|
import javax.validation.ValidatorFactory;
|
||||||
|
|
||||||
|
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||||
import org.apache.openjpa.event.LifecycleEvent;
|
import org.apache.openjpa.event.LifecycleEvent;
|
||||||
|
import org.apache.openjpa.lib.conf.Configuration;
|
||||||
import org.apache.openjpa.lib.util.Localizer;
|
import org.apache.openjpa.lib.util.Localizer;
|
||||||
import org.apache.openjpa.validation.AbstractValidator;
|
import org.apache.openjpa.validation.AbstractValidator;
|
||||||
import org.apache.openjpa.validation.ValidationException;
|
import org.apache.openjpa.validation.ValidationException;
|
||||||
@ -43,6 +45,8 @@ public class ValidatorImpl extends AbstractValidator {
|
|||||||
private ValidatorFactory _validatorFactory = null;
|
private ValidatorFactory _validatorFactory = null;
|
||||||
private Validator _validator = null;
|
private Validator _validator = null;
|
||||||
private ValidationMode _mode = ValidationMode.AUTO;
|
private ValidationMode _mode = ValidationMode.AUTO;
|
||||||
|
private OpenJPAConfiguration _conf = null;
|
||||||
|
|
||||||
|
|
||||||
// A map storing the validation groups to use for a particular event type
|
// A map storing the validation groups to use for a particular event type
|
||||||
private Map<Integer, Class<?>[]> _validationGroups =
|
private Map<Integer, Class<?>[]> _validationGroups =
|
||||||
@ -61,7 +65,7 @@ public class ValidatorImpl extends AbstractValidator {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
_vgMapping.put(VG_PRE_PERSIST,
|
_vgMapping.put(VG_PRE_PERSIST,
|
||||||
LifecycleEvent.BEFORE_STORE);
|
LifecycleEvent.BEFORE_PERSIST);
|
||||||
_vgMapping.put(VG_PRE_REMOVE,
|
_vgMapping.put(VG_PRE_REMOVE,
|
||||||
LifecycleEvent.BEFORE_DELETE);
|
LifecycleEvent.BEFORE_DELETE);
|
||||||
_vgMapping.put(VG_PRE_UPDATE,
|
_vgMapping.put(VG_PRE_UPDATE,
|
||||||
@ -77,6 +81,25 @@ public class ValidatorImpl extends AbstractValidator {
|
|||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ValidatorImpl(Configuration conf) {
|
||||||
|
if (conf instanceof OpenJPAConfiguration) {
|
||||||
|
_conf = (OpenJPAConfiguration)conf;
|
||||||
|
Object validatorFactory = _conf.getValidationFactoryInstance();
|
||||||
|
String mode = _conf.getValidationMode();
|
||||||
|
_mode = Enum.valueOf(ValidationMode.class, mode);
|
||||||
|
if (validatorFactory != null) {
|
||||||
|
if (validatorFactory instanceof ValidatorFactory) {
|
||||||
|
_validatorFactory = (ValidatorFactory)validatorFactory;
|
||||||
|
} else {
|
||||||
|
// Supplied object was not an instance of a ValidatorFactory
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
_loc.get("invalid-factory").getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type-specific constructor
|
* Type-specific constructor
|
||||||
* Returns an Exception if a Validator could not be created.
|
* Returns an Exception if a Validator could not be created.
|
||||||
@ -95,27 +118,6 @@ public class ValidatorImpl extends AbstractValidator {
|
|||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic-type constructor
|
|
||||||
* Returns an Exception if a Validator could not be created.
|
|
||||||
* @param validatorFactory an instance to the validatorFactory
|
|
||||||
* @param mode validation mode enum as string value
|
|
||||||
*/
|
|
||||||
public ValidatorImpl(Object validatorFactory,
|
|
||||||
String mode) {
|
|
||||||
_mode = Enum.valueOf(ValidationMode.class, mode);
|
|
||||||
if (validatorFactory != null) {
|
|
||||||
if (validatorFactory instanceof ValidatorFactory) {
|
|
||||||
_validatorFactory = (ValidatorFactory)validatorFactory;
|
|
||||||
} else {
|
|
||||||
// Supplied object was not an instance of a ValidatorFactory.
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
_loc.get("invalid-factory").getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common setup code factored out of the constructors
|
* Common setup code factored out of the constructors
|
||||||
*/
|
*/
|
||||||
@ -140,8 +142,19 @@ public class ValidatorImpl extends AbstractValidator {
|
|||||||
_loc.get("no-validator").getMessage());
|
_loc.get("no-validator").getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// add in default validation groups, which can be over-ridden later
|
if (_conf != null) {
|
||||||
addDefaultValidationGroups();
|
addValidationGroup(VG_PRE_PERSIST,
|
||||||
|
_conf.getValidationGroupPrePersist());
|
||||||
|
addValidationGroup(VG_PRE_UPDATE,
|
||||||
|
_conf.getValidationGroupPreUpdate());
|
||||||
|
addValidationGroup(VG_PRE_REMOVE,
|
||||||
|
_conf.getValidationGroupPreRemove());
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// add in default validation groups, which can be over-ridden later
|
||||||
|
addDefaultValidationGroups();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// A Validator should not be created based on the supplied ValidationMode.
|
// A Validator should not be created based on the supplied ValidationMode.
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
@ -181,6 +194,54 @@ public class ValidatorImpl extends AbstractValidator {
|
|||||||
_validationGroups.put(event, validationGroup);
|
_validationGroups.put(event, validationGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the validation group(s) for the specified event. Event definitions
|
||||||
|
* are defined in LifecycleEvent
|
||||||
|
* @param event
|
||||||
|
* @param group
|
||||||
|
*/
|
||||||
|
public void addValidationGroup(String validationGroupName, String group) {
|
||||||
|
Integer event = findEvent(validationGroupName);
|
||||||
|
if (event != null) {
|
||||||
|
Class<?>[] vgs = getValidationGroup(validationGroupName, group);
|
||||||
|
if (vgs != null) {
|
||||||
|
addValidationGroup(event, vgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// There were no events found for group "{0}".
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
_loc.get("no-group-events", validationGroupName).getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a comma separated list of validation groups into an array
|
||||||
|
* of classes.
|
||||||
|
* @param group
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Class<?>[] getValidationGroup(String vgName, String group) {
|
||||||
|
Class<?>[] vgGrp = null;
|
||||||
|
if (group == null || group.trim().length() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] strClasses = group.split(",");
|
||||||
|
if (strClasses.length > 0) {
|
||||||
|
vgGrp = new Class<?>[strClasses.length];
|
||||||
|
for (int i = 0; i < strClasses.length; i++) {
|
||||||
|
try {
|
||||||
|
vgGrp[i] = Class.forName(strClasses[i]);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
_loc.get("invalid-validation-group", strClasses[i],
|
||||||
|
vgName).getMessage(), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vgGrp;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the validation groups to be validated for a specified event
|
* Return the validation groups to be validated for a specified event
|
||||||
* @param event Lifecycle event id
|
* @param event Lifecycle event id
|
||||||
|
@ -34,4 +34,5 @@ validate-property-failed: A validation constraint failure occurred for \
|
|||||||
property "{1}" in class "{0}".
|
property "{1}" in class "{0}".
|
||||||
validate-value-failed: A validation constraint failure occurred for \
|
validate-value-failed: A validation constraint failure occurred for \
|
||||||
value "{2}" of property "{1}" in class "{0}".
|
value "{2}" of property "{1}" in class "{0}".
|
||||||
|
invalid-validation-group: The class "{0}" specified in the validation group \
|
||||||
|
property "{1}" is not valid or could not be loaded.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user