Hibernate SVN: r16510 - in validator/trunk/hibernate-validator/src: main/java/org/hibernate/validation/engine/resolver and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-05-05 08:40:55 -0400 (Tue, 05 May 2009)
New Revision: 16510
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/DefaultTraversableResolver.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/JPATraversableResolver.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/SingleThreadCachedTraversableResolver.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/CachedTraversableResolverTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/SnifferTraversableResolver.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/TraversableResolverTest.java
Log:
BVAL-152 HV-160 TraversableResolver should differentiate reachability and cascadability
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java 2009-05-05 12:36:30 UTC (rev 16509)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java 2009-05-05 12:40:55 UTC (rev 16510)
@@ -289,7 +289,7 @@
return false;
}
- return traversableResolver.isTraversable(
+ return traversableResolver.isReachable(
peekCurrentBean(),
peekProperty(),
getRootBeanClass(),
@@ -299,12 +299,24 @@
}
public boolean isCascadeRequired(Member member) {
- return traversableResolver.isTraversable(
- peekCurrentBean(),
- peekProperty(),
- getRootBeanClass(),
- peekParentPath(),
- member instanceof Field ? ElementType.FIELD : ElementType.METHOD
+ final ElementType type = member instanceof Field ? ElementType.FIELD : ElementType.METHOD;
+ final String parentPath = peekParentPath();
+ final Class<T> rootBeanType = getRootBeanClass();
+ final String traversableProperty = peekProperty();
+ final Object traversableobject = peekCurrentBean();
+ return traversableResolver.isReachable(
+ traversableobject,
+ traversableProperty,
+ rootBeanType,
+ parentPath,
+ type
+ )
+ && traversableResolver.isCascadable(
+ traversableobject,
+ traversableProperty,
+ rootBeanType,
+ parentPath,
+ type
);
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-05-05 12:36:30 UTC (rev 16509)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-05-05 12:40:55 UTC (rev 16510)
@@ -260,7 +260,6 @@
*/
private <T> boolean validateConstraintsForCurrentGroup(ExecutionContext<T> executionContext, BeanMetaData<T> beanMetaData) {
boolean validationSuccessful = true;
- //FIXME isValidationRequired for all constraints in a given context May need to divide by elementType
for ( MetaConstraint<T, ?> metaConstraint : beanMetaData.geMetaConstraintList() ) {
executionContext.pushProperty( metaConstraint.getPropertyName() );
if ( executionContext.isValidationRequired( metaConstraint ) ) {
@@ -272,10 +271,11 @@
return validationSuccessful;
}
+ //this method must always be called after validateConstraints for the same context
+ //TODO define a validate that calls validateConstraints and then validateCascadedConstraints
private <T> void validateCascadedConstraints(ExecutionContext<T> context) {
List<Member> cascadedMembers = getBeanMetaData( context.peekCurrentBeanType() )
.getCascadedMembers();
- //FIXME isValidationRequired for all constraints in a given context May need to divide by elementType
for ( Member member : cascadedMembers ) {
Type type = ReflectionHelper.typeOf( member );
context.pushProperty( ReflectionHelper.getPropertyName( member ) );
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/DefaultTraversableResolver.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/DefaultTraversableResolver.java 2009-05-05 12:36:30 UTC (rev 16509)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/DefaultTraversableResolver.java 2009-05-05 12:40:55 UTC (rev 16510)
@@ -38,12 +38,6 @@
detectJPA();
}
- public boolean isTraversable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
- return jpaTraversableResolver == null || jpaTraversableResolver.isTraversable(
- traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType
- );
- }
-
/**
* Tries to load detect and load JPA.
*/
@@ -88,4 +82,16 @@
);
}
}
+
+ public boolean isReachable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ return jpaTraversableResolver == null || jpaTraversableResolver.isReachable(
+ traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType
+ );
+ }
+
+ public boolean isCascadable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ return jpaTraversableResolver == null || jpaTraversableResolver.isCascadable(
+ traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType
+ );
+ }
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/JPATraversableResolver.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/JPATraversableResolver.java 2009-05-05 12:36:30 UTC (rev 16509)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/JPATraversableResolver.java 2009-05-05 12:40:55 UTC (rev 16510)
@@ -23,11 +23,16 @@
/**
* @author Hardy Ferentschik
+ * @author Emmanuel Bernard
*/
public class JPATraversableResolver implements TraversableResolver {
- public boolean isTraversable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ public boolean isReachable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
return traversableObject == null ||
Persistence.getPersistenceUtil().isLoaded( traversableObject, traversableProperty );
}
+
+ public boolean isCascadable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ return true;
+ }
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/SingleThreadCachedTraversableResolver.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/SingleThreadCachedTraversableResolver.java 2009-05-05 12:36:30 UTC (rev 16509)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/resolver/SingleThreadCachedTraversableResolver.java 2009-05-05 12:40:55 UTC (rev 16510)
@@ -14,110 +14,123 @@
*/
public class SingleThreadCachedTraversableResolver implements TraversableResolver {
private TraversableResolver delegate;
- private Map<LazyHolder, LazyHolder> lazys = new HashMap<LazyHolder, LazyHolder>();
private Map<TraversableHolder, TraversableHolder> traversables = new HashMap<TraversableHolder, TraversableHolder>();
public SingleThreadCachedTraversableResolver(TraversableResolver delegate) {
this.delegate = delegate;
}
- public boolean isTraversable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
- Boolean delegateResult = null;
-
- //if traversableObject is null we can't determine lazyness
- if (traversableObject != null) {
- LazyHolder currentLH = new LazyHolder( traversableObject, traversableProperty );
- LazyHolder cachedLH = lazys.get( currentLH );
- if (cachedLH == null) {
- delegateResult = delegate.isTraversable(
- traversableObject,
- traversableProperty,
- rootBeanType,
- pathToTraversableObject,
- elementType );
- currentLH.isTraversable = delegateResult;
- lazys.put( currentLH, currentLH );
- cachedLH = currentLH;
- }
- if ( ! cachedLH.isTraversable ) return false;
+ public boolean isReachable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ TraversableHolder currentLH = new TraversableHolder( traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType );
+ TraversableHolder cachedLH = traversables.get( currentLH );
+ if (cachedLH == null) {
+ currentLH.isReachable = delegate.isReachable(
+ traversableObject,
+ traversableProperty,
+ rootBeanType,
+ pathToTraversableObject,
+ elementType );
+ traversables.put( currentLH, currentLH );
+ cachedLH = currentLH;
}
-
-
- TraversableHolder currentTH = new TraversableHolder( rootBeanType, pathToTraversableObject, elementType );
- TraversableHolder cachedTH = traversables.get(currentTH);
- if ( cachedTH == null ) {
- if (delegateResult == null) {
- delegateResult = delegate.isTraversable(
+ else if ( cachedLH.isReachable == null ) {
+ cachedLH.isReachable = delegate.isReachable(
traversableObject,
traversableProperty,
rootBeanType,
pathToTraversableObject,
elementType );
- }
- currentTH.isTraversable = delegateResult;
- traversables.put( currentTH, currentTH );
- cachedTH = currentTH;
}
- return cachedTH.isTraversable;
+ return cachedLH.isReachable;
}
- private static class LazyHolder {
- private final Object traversableObject;
- private final String traversableProperty;
- private final int hashCode;
- private boolean isTraversable;
-
- private LazyHolder(Object traversableObject, String traversableProperty) {
- this.traversableObject = traversableObject;
- this.traversableProperty = traversableProperty == null ? "" : traversableProperty;
- hashCode = this.traversableObject.hashCode() + this.traversableProperty.hashCode();
+ public boolean isCascadable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ TraversableHolder currentLH = new TraversableHolder( traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType );
+ TraversableHolder cachedLH = traversables.get( currentLH );
+ if (cachedLH == null) {
+ currentLH.isCascadable = delegate.isCascadable(
+ traversableObject,
+ traversableProperty,
+ rootBeanType,
+ pathToTraversableObject,
+ elementType );
+ traversables.put( currentLH, currentLH );
+ cachedLH = currentLH;
}
-
- @Override
- public int hashCode() {
- return hashCode;
+ else if ( cachedLH.isCascadable == null ) {
+ cachedLH.isCascadable = delegate.isCascadable(
+ traversableObject,
+ traversableProperty,
+ rootBeanType,
+ pathToTraversableObject,
+ elementType );
}
-
- @Override
- public boolean equals(Object obj) {
- if ( ! (obj instanceof LazyHolder) ) {
- return false;
- }
- LazyHolder that = (LazyHolder) obj;
- return traversableObject == that.traversableObject
- && traversableProperty.equals( that.traversableProperty );
- }
+ return cachedLH.isCascadable;
}
private static class TraversableHolder {
+ private final Object traversableObject;
+ private final String traversableProperty;
private final Class<?> rootBeanType;
private final String pathToTraversableObject;
private final ElementType elementType;
private final int hashCode;
- private boolean isTraversable;
+ private Boolean isReachable;
+ private Boolean isCascadable;
- private TraversableHolder(Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+
+ private TraversableHolder(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ this.traversableObject = traversableObject;
+ this.traversableProperty = traversableProperty;
this.rootBeanType = rootBeanType;
this.pathToTraversableObject = pathToTraversableObject == null ? "" : pathToTraversableObject;
this.elementType = elementType;
- hashCode = this.rootBeanType.hashCode() + this.pathToTraversableObject.hashCode() + this.elementType.hashCode();
+ this.hashCode = buildHashCode();
}
@Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+
+ TraversableHolder that = ( TraversableHolder ) o;
+
+ if ( elementType != that.elementType ) {
+ return false;
+ }
+ if ( !pathToTraversableObject.equals( that.pathToTraversableObject ) ) {
+ return false;
+ }
+ if ( !rootBeanType.equals( that.rootBeanType ) ) {
+ return false;
+ }
+ if ( traversableObject != null ? !traversableObject.equals( that.traversableObject ) : that.traversableObject != null ) {
+ return false;
+ }
+ if ( !traversableProperty.equals( that.traversableProperty ) ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
public int hashCode() {
return hashCode;
}
- @Override
- public boolean equals(Object obj) {
- if ( ! (obj instanceof TraversableHolder) ) {
- return false;
- }
- TraversableHolder that = (TraversableHolder) obj;
- return rootBeanType == that.rootBeanType
- && pathToTraversableObject.equals( that.pathToTraversableObject )
- && elementType == that.elementType;
+ public int buildHashCode() {
+ int result = traversableObject != null ? traversableObject.hashCode() : 0;
+ result = 31 * result + traversableProperty.hashCode();
+ result = 31 * result + rootBeanType.hashCode();
+ result = 31 * result + pathToTraversableObject.hashCode();
+ result = 31 * result + elementType.hashCode();
+ return result;
}
}
}
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java 2009-05-05 12:36:30 UTC (rev 16509)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java 2009-05-05 12:40:55 UTC (rev 16510)
@@ -273,9 +273,13 @@
configuration = Validation.byDefaultProvider().configure();
configuration.traversableResolver(
new TraversableResolver() {
- public boolean isTraversable(Object o, String s, Class<?> aClass, String s1, ElementType elementType) {
+ public boolean isReachable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
return false;
}
+
+ public boolean isCascadable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ return false;
+ }
}
);
factory = configuration.buildValidatorFactory();
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/CachedTraversableResolverTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/CachedTraversableResolverTest.java 2009-05-05 12:36:30 UTC (rev 16509)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/CachedTraversableResolverTest.java 2009-05-05 12:40:55 UTC (rev 16510)
@@ -57,19 +57,24 @@
}
private static class AskOnceTR implements TraversableResolver {
- private Set<Holder> asked = new HashSet<Holder>();
+ private Set<Holder> askedReach = new HashSet<Holder>();
+ private Set<Holder> askedCascade = new HashSet<Holder>();
- public Set<Holder> getAsked() {
- return asked;
- }
-
- public boolean isTraversable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ private boolean isTraversable(Set<Holder> asked, Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
Holder h = new Holder(traversableObject, traversableProperty);
- if (asked.contains( h )) throw new IllegalStateException( "Called twice" );
+ if ( asked.contains( h )) throw new IllegalStateException( "Called twice" );
asked.add( h );
return true;
}
+ public boolean isReachable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ return isTraversable( askedReach, traversableObject, traversableProperty, rootBeanType, pathToTraversableObject,elementType );
+ }
+
+ public boolean isCascadable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ return isTraversable( askedCascade, traversableObject, traversableProperty, rootBeanType, pathToTraversableObject,elementType );
+ }
+
public static class Holder {
Object NULL = new Object();
Object to;
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/SnifferTraversableResolver.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/SnifferTraversableResolver.java 2009-05-05 12:36:30 UTC (rev 16509)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/SnifferTraversableResolver.java 2009-05-05 12:40:55 UTC (rev 16510)
@@ -9,23 +9,30 @@
* @author Emmanuel Bernard
*/
public class SnifferTraversableResolver implements TraversableResolver {
- Set<String> paths = new HashSet<String>();
- Set<Call> calls = new HashSet<Call>();
+ Set<String> reachPaths = new HashSet<String>();
+ Set<String> cascadePaths = new HashSet<String>();
+ Set<Call> reachCalls = new HashSet<Call>();
+ Set<Call> cascadeCalls = new HashSet<Call>();
public SnifferTraversableResolver(Suit suit) {
- calls.add( new Call(suit, "size", Suit.class, "", ElementType.FIELD ) );
- calls.add( new Call(suit, "trousers", Suit.class, "", ElementType.FIELD ) );
- calls.add( new Call(suit.getTrousers(), "length", Suit.class, "trousers", ElementType.FIELD ) );
- calls.add( new Call(suit, "jacket", Suit.class, "", ElementType.METHOD ) );
- calls.add( new Call(suit.getJacket(), "width", Suit.class, "jacket", ElementType.METHOD ) );
+ reachCalls.add( new Call(suit, "size", Suit.class, "", ElementType.FIELD ) );
+ reachCalls.add( new Call(suit, "trousers", Suit.class, "", ElementType.FIELD ) );
+ cascadeCalls.add( new Call(suit, "trousers", Suit.class, "", ElementType.FIELD ) );
+ reachCalls.add( new Call(suit.getTrousers(), "length", Suit.class, "trousers", ElementType.FIELD ) );
+ reachCalls.add( new Call(suit, "jacket", Suit.class, "", ElementType.METHOD ) );
+ cascadeCalls.add( new Call(suit, "jacket", Suit.class, "", ElementType.METHOD ) );
+ reachCalls.add( new Call(suit.getJacket(), "width", Suit.class, "jacket", ElementType.METHOD ) );
}
- public Set<String> getPaths() {
- return paths;
+ public Set<String> getReachPaths() {
+ return reachPaths;
}
- //TODO add test with correct paths and types to make sure the impl does not mess it up
- public boolean isTraversable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ public Set<String> getCascadePaths() {
+ return cascadePaths;
+ }
+
+ public boolean isTraversable(Set<Call> calls, Set<String> paths, Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
String path = "";
if (! (pathToTraversableObject == null || pathToTraversableObject.length() == 0 ) ) {
path = pathToTraversableObject + ".";
@@ -39,6 +46,14 @@
return true;
}
+ public boolean isReachable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ return isTraversable( reachCalls, reachPaths, traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType );
+ }
+
+ public boolean isCascadable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ return isTraversable( cascadeCalls, cascadePaths, traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType );
+ }
+
private static final class Call {
private Object traversableObject;
private String traversableProperty;
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/TraversableResolverTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/TraversableResolverTest.java 2009-05-05 12:36:30 UTC (rev 16509)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/TraversableResolverTest.java 2009-05-05 12:40:55 UTC (rev 16510)
@@ -1,9 +1,5 @@
package org.hibernate.validation.engine.resolver;
-import java.lang.annotation.ElementType;
-import java.util.HashSet;
-import java.util.Set;
-import javax.validation.TraversableResolver;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.Validator;
@@ -12,8 +8,6 @@
import org.testng.annotations.Test;
import static org.testng.Assert.*;
-import org.hibernate.validation.engine.HibernateValidatorConfiguration;
-
/**
* @author Emmanuel Bernard
*/
@@ -36,6 +30,7 @@
//Raises an IllegalStateException if something goes wrong
v.validate( suit, Default.class, Cloth.class );
- assertEquals( 5, resolver.getPaths().size() );
+ assertEquals( 5, resolver.getReachPaths().size() );
+ assertEquals( 2, resolver.getCascadePaths().size() );
}
}
\ No newline at end of file
15 years, 7 months
Hibernate SVN: r16509 - beanvalidation/trunk/validation-api/src/main/java/javax/validation.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-05-05 08:36:30 -0400 (Tue, 05 May 2009)
New Revision: 16509
Modified:
beanvalidation/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java
Log:
BVAL-152 TraversableResolver should differentiate reachability and cascadability
Modified: beanvalidation/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java
===================================================================
--- beanvalidation/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java 2009-05-05 10:12:04 UTC (rev 16508)
+++ beanvalidation/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java 2009-05-05 12:36:30 UTC (rev 16509)
@@ -21,7 +21,7 @@
/**
* Contract determining if a property can be accessed by the Bean Validation provider
- * This contract is called for each property either validated or traversed.
+ * This contract is called for each property either validated or cascaded.
*
* A traversable resolver implementation must be thread-safe.
*
@@ -29,7 +29,7 @@
*/
public interface TraversableResolver {
/**
- * Determine if a property can be traversed by Bean Validation.
+ * Determine if Bean Validation is allowed to reach the property state
*
* @param traversableObject object hosting <code>traversableProperty</code>, null if validateValue is called
* @param traversableProperty name of the traversable property.
@@ -40,12 +40,37 @@
* (using the path specification defined by Bean Validator).
* @param elementType either <code>FIELD</code> or <code>METHOD</code>.
*
- * @return <code>true</code> if the property is traversable by Bean Validation,
+ * @return <code>true</code> if Bean Validation is allowed to reach the property state,
* <code>false</code> otherwise.
*/
- boolean isTraversable(Object traversableObject,
+ boolean isReachable(Object traversableObject,
String traversableProperty,
Class<?> rootBeanType,
String pathToTraversableObject,
ElementType elementType);
+
+ /**
+ * Determine if Bean Validation is allowed to cascade validation on
+ * the bean instance returned by the property value
+ * marked as <code>@Valid</code>.
+ * Note that this method is called only if isReachable returns true for the same set of
+ * arguments and if the property is marked as <code>@Valid</code>
+ *
+ * @param traversableObject object hosting <code>traversableProperty</code>, null if validateValue is called
+ * @param traversableProperty name of the traversable property.
+ * @param rootBeanType type of the root object passed to the Validator.
+ * @param pathToTraversableObject path from the root object to
+ * <code>traversableObject</code> ("" if the <code>traversableObject</code>
+ * is the root object)
+ * (using the path specification defined by Bean Validator).
+ * @param elementType either <code>FIELD</code> or <code>METHOD</code>.
+ *
+ * @return <code>true</code> if Bean Validation is allowed to cascade validation,
+ * <code>false</code> otherwise.
+ */
+ boolean isCascadable(Object traversableObject,
+ String traversableProperty,
+ Class<?> rootBeanType,
+ String pathToTraversableObject,
+ ElementType elementType);
}
15 years, 7 months
Hibernate SVN: r16508 - validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-05-05 06:12:04 -0400 (Tue, 05 May 2009)
New Revision: 16508
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/Child.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ChildFirst.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/Parent.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ParentSecond.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ProperOrder.java
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java
Log:
add tests related to sequences and graphs
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/Child.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/Child.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/Child.java 2009-05-05 10:12:04 UTC (rev 16508)
@@ -0,0 +1,19 @@
+package org.hibernate.validation.engine.graphnavigation;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class Child {
+ private String name;
+
+ @NotNull(groups = ChildFirst.class)
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ChildFirst.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ChildFirst.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ChildFirst.java 2009-05-05 10:12:04 UTC (rev 16508)
@@ -0,0 +1,7 @@
+package org.hibernate.validation.engine.graphnavigation;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface ChildFirst {
+}
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java 2009-05-04 17:06:34 UTC (rev 16507)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java 2009-05-05 10:12:04 UTC (rev 16508)
@@ -22,6 +22,7 @@
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
+import javax.validation.Validation;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
@@ -111,4 +112,14 @@
constraintViolations = validator.validate( john );
assertEquals( constraintViolations.size(), 0, "Wrong number of constraints" );
}
+
+ @Test
+ public void testFullGraphValidationBeforeNextGroupInSequence() {
+ Parent p = new Parent();
+ p.setChild( new Child() );
+ Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
+ Set<ConstraintViolation<Parent>> errors = validator.validate( p, ProperOrder.class );
+ assertEquals( 1, errors.size() );
+ assertEquals( "child.name", errors.iterator().next().getPropertyPath() );
+ }
}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/Parent.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/Parent.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/Parent.java 2009-05-05 10:12:04 UTC (rev 16508)
@@ -0,0 +1,30 @@
+package org.hibernate.validation.engine.graphnavigation;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.Valid;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class Parent {
+ private String name;
+ private Child child;
+
+ @NotNull(groups = ParentSecond.class)
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Valid
+ public Child getChild() {
+ return child;
+ }
+
+ public void setChild(Child child) {
+ this.child = child;
+ }
+}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ParentSecond.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ParentSecond.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ParentSecond.java 2009-05-05 10:12:04 UTC (rev 16508)
@@ -0,0 +1,7 @@
+package org.hibernate.validation.engine.graphnavigation;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface ParentSecond {
+}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ProperOrder.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ProperOrder.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/ProperOrder.java 2009-05-05 10:12:04 UTC (rev 16508)
@@ -0,0 +1,10 @@
+package org.hibernate.validation.engine.graphnavigation;
+
+import javax.validation.GroupSequence;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@GroupSequence( {ChildFirst.class, ParentSecond.class } )
+public interface ProperOrder {
+}
15 years, 7 months
Hibernate SVN: r16507 - in validator/trunk/hibernate-validator/src: test/java/org/hibernate/validation/constraints and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-05-04 13:06:34 -0400 (Mon, 04 May 2009)
New Revision: 16507
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/BoundariesConstraintValidator.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/CustomConstraintValidatorTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/Positive.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/PositiveConstraintValidator.java
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java
Log:
HV-146 ConstraintValidator impls cannot inherit from a super class implementing ConstraintValidator
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java 2009-05-04 15:34:08 UTC (rev 16506)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java 2009-05-04 17:06:34 UTC (rev 16507)
@@ -86,16 +86,8 @@
}
else if ( type instanceof Class ) {
Class clazz = ( Class ) type;
- Type returnedType = resolveTypes( resolvedTypes, clazz.getGenericSuperclass() );
- if ( returnedType != null ) {
- return returnedType;
- }
- for ( Type genericInterface : clazz.getGenericInterfaces() ) {
- returnedType = resolveTypes( resolvedTypes, genericInterface );
- if ( returnedType != null ) {
- return returnedType;
- }
- }
+ final Type returnedType = resolveTypeForClassAndHierarchy( resolvedTypes, clazz );
+ if ( returnedType != null) return returnedType;
}
else if ( type instanceof ParameterizedType ) {
ParameterizedType paramType = ( ParameterizedType ) type;
@@ -116,13 +108,25 @@
return type;
}
else {
- resolveTypes( resolvedTypes, rawType.getGenericSuperclass() );
- for ( Type genericInterface : rawType.getGenericInterfaces() ) {
- resolveTypes( resolvedTypes, genericInterface );
- }
+ Type returnedType = resolveTypeForClassAndHierarchy( resolvedTypes, rawType );
+ if ( returnedType != null) return returnedType;
}
}
//else we don't care I think
return null;
}
+
+ private static Type resolveTypeForClassAndHierarchy(Map<Type, Type> resolvedTypes, Class<?> clazz) {
+ Type returnedType = resolveTypes( resolvedTypes, clazz.getGenericSuperclass() );
+ if ( returnedType != null ) {
+ return returnedType;
+ }
+ for ( Type genericInterface : clazz.getGenericInterfaces() ) {
+ returnedType = resolveTypes( resolvedTypes, genericInterface );
+ if ( returnedType != null ) {
+ return returnedType;
+ }
+ }
+ return null;
+ }
}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/BoundariesConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/BoundariesConstraintValidator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/BoundariesConstraintValidator.java 2009-05-04 17:06:34 UTC (rev 16507)
@@ -0,0 +1,22 @@
+package org.hibernate.validation.constraints.custom;
+
+import java.lang.annotation.Annotation;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public abstract class BoundariesConstraintValidator<T extends Annotation> implements ConstraintValidator<T, Integer> {
+ private int low;
+ private int high;
+
+ protected void initialize(int low, int high) {
+ this.low = low;
+ this.high = high;
+ }
+
+ public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
+ return value >= low && value <= high;
+ }
+}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/CustomConstraintValidatorTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/CustomConstraintValidatorTest.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/CustomConstraintValidatorTest.java 2009-05-04 17:06:34 UTC (rev 16507)
@@ -0,0 +1,33 @@
+package org.hibernate.validation.constraints.custom;
+
+import java.util.Set;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ConstraintViolation;
+import javax.validation.PropertyDescriptor;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/**
+ * @author Emmanuel Bernard
+ */
+
+public class CustomConstraintValidatorTest {
+
+ @Test
+ public void testInheritedConstraintValidationImpl() {
+ Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
+ Phone p = new Phone();
+ p.size = -2;
+ final PropertyDescriptor propertyDescriptor = validator.getConstraintsForClass( Phone.class )
+ .getConstraintsForProperty( "size" );
+ assertNotNull( propertyDescriptor );
+ final Set<ConstraintViolation<Phone>> constraintViolations = validator.validate( p );
+ assertEquals( 1, constraintViolations.size() );
+ }
+
+ public static class Phone {
+ @Positive public int size;
+ }
+}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/Positive.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/Positive.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/Positive.java 2009-05-04 17:06:34 UTC (rev 16507)
@@ -0,0 +1,22 @@
+package org.hibernate.validation.constraints.custom;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Documented;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import javax.validation.Constraint;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Constraint( validatedBy = { PositiveConstraintValidator.class })
+@Target({ METHOD, FIELD, ANNOTATION_TYPE })
+@Retention(RUNTIME)
+@Documented
+public @interface Positive {
+ String message() default "{validation.positive}";
+ Class<?>[] groups() default {};
+}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/PositiveConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/PositiveConstraintValidator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/custom/PositiveConstraintValidator.java 2009-05-04 17:06:34 UTC (rev 16507)
@@ -0,0 +1,10 @@
+package org.hibernate.validation.constraints.custom;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class PositiveConstraintValidator extends BoundariesConstraintValidator<Positive> {
+ public void initialize(Positive constraintAnnotation) {
+ super.initialize( 0, Integer.MAX_VALUE );
+ }
+}
15 years, 7 months
Hibernate SVN: r16506 - in validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation: util and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-05-04 11:34:08 -0400 (Mon, 04 May 2009)
New Revision: 16506
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
Log:
HV-149 ReflectionHelper.containsMethod ignores "is" methods
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-05-04 12:42:25 UTC (rev 16505)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-05-04 15:34:08 UTC (rev 16506)
@@ -544,12 +544,17 @@
private <T> Object collectMetaConstraintsForPath(Class<T> clazz, Object value, PropertyIterator propertyIter, Set<MetaConstraint<T, ?>> metaConstraints) {
propertyIter.split();
+ final BeanMetaData<T> metaData = getBeanMetaData( clazz );
if ( !propertyIter.hasNext() ) {
- if ( !ReflectionHelper.containsMember( clazz, propertyIter.getHead() ) ) {
+ //use metadata first as ReflectionHelper#containsMember is slow
+ //TODO store some metadata here?
+ if ( metaData.getPropertyDescriptor( propertyIter.getHead() ) == null
+ && !ReflectionHelper.containsMember( clazz, propertyIter.getHead() ) ) {
+ //TODO better error report
throw new IllegalArgumentException( "Invalid property path." );
}
- List<MetaConstraint<T, ? extends Annotation>> metaConstraintList = getBeanMetaData( clazz ).geMetaConstraintList();
+ List<MetaConstraint<T, ? extends Annotation>> metaConstraintList = metaData.geMetaConstraintList();
for ( MetaConstraint<T, ?> metaConstraint : metaConstraintList ) {
if ( metaConstraint.getPropertyName().equals( propertyIter.getHead() ) ) {
metaConstraints.add( metaConstraint );
@@ -557,7 +562,7 @@
}
}
else {
- List<Member> cascadedMembers = getBeanMetaData( clazz ).getCascadedMembers();
+ List<Member> cascadedMembers = metaData.getCascadedMembers();
for ( Member m : cascadedMembers ) {
if ( ReflectionHelper.getPropertyName( m ).equals( propertyIter.getHead() ) ) {
Type type = ReflectionHelper.typeOf( m );
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java 2009-05-04 12:42:25 UTC (rev 16505)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java 2009-05-04 15:34:08 UTC (rev 16506)
@@ -394,7 +394,15 @@
*/
public static boolean containsMethod(Class<?> clazz, String methodName) {
try {
- clazz.getMethod( "get" + methodName.substring( 0, 1 ).toUpperCase() + methodName.substring( 1 ) );
+ char string[] = methodName.toCharArray();
+ string[0] = Character.toUpperCase( string[0] );
+ methodName = new String( string );
+ try {
+ clazz.getMethod( "get" + methodName );
+ }
+ catch ( NoSuchMethodException e ) {
+ clazz.getMethod( "is" + methodName );
+ }
return true;
}
catch ( NoSuchMethodException e ) {
15 years, 7 months
Hibernate SVN: r16505 - in validator/trunk/hibernate-validator/src: test/java/org/hibernate/validation/engine/resolver and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-05-04 08:42:25 -0400 (Mon, 04 May 2009)
New Revision: 16505
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/SnifferTraversableResolver.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/TraversableResolverTest.java
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
Log:
HV-157 cascading no longer executed if isTraversable returns false
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java 2009-05-03 21:41:37 UTC (rev 16504)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java 2009-05-04 12:42:25 UTC (rev 16505)
@@ -25,6 +25,9 @@
import java.util.Map;
import java.util.Set;
import java.util.Stack;
+import java.lang.reflect.Member;
+import java.lang.reflect.Field;
+import java.lang.annotation.ElementType;
import javax.validation.ConstraintDescriptor;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.ConstraintViolation;
@@ -293,8 +296,18 @@
peekParentPath(),
metaConstraint.getElementType()
);
- }
+ }
+ public boolean isCascadeRequired(Member member) {
+ return traversableResolver.isTraversable(
+ peekCurrentBean(),
+ peekProperty(),
+ getRootBeanClass(),
+ peekParentPath(),
+ member instanceof Field ? ElementType.FIELD : ElementType.METHOD
+ );
+ }
+
public List<ConstraintViolationImpl<T>> createConstraintViolations(Object value, ConstraintValidatorContextImpl constraintValidatorContext) {
List<ConstraintViolationImpl<T>> constraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
for ( ConstraintValidatorContextImpl.ErrorMessage error : constraintValidatorContext.getErrorMessages() ) {
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-05-03 21:41:37 UTC (rev 16504)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-05-04 12:42:25 UTC (rev 16505)
@@ -279,10 +279,12 @@
for ( Member member : cascadedMembers ) {
Type type = ReflectionHelper.typeOf( member );
context.pushProperty( ReflectionHelper.getPropertyName( member ) );
- Object value = ReflectionHelper.getValue( member, context.peekCurrentBean() );
- if ( value != null ) {
- Iterator<?> iter = createIteratorForCascadedValue( context, type, value );
- validateCascadedConstraint( context, iter );
+ if ( context.isCascadeRequired( member ) ) {
+ Object value = ReflectionHelper.getValue( member, context.peekCurrentBean() );
+ if ( value != null ) {
+ Iterator<?> iter = createIteratorForCascadedValue( context, type, value );
+ validateCascadedConstraint( context, iter );
+ }
}
context.popProperty();
}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/SnifferTraversableResolver.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/SnifferTraversableResolver.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/SnifferTraversableResolver.java 2009-05-04 12:42:25 UTC (rev 16505)
@@ -0,0 +1,108 @@
+package org.hibernate.validation.engine.resolver;
+
+import java.lang.annotation.ElementType;
+import java.util.Set;
+import java.util.HashSet;
+import javax.validation.TraversableResolver;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class SnifferTraversableResolver implements TraversableResolver {
+ Set<String> paths = new HashSet<String>();
+ Set<Call> calls = new HashSet<Call>();
+
+ public SnifferTraversableResolver(Suit suit) {
+ calls.add( new Call(suit, "size", Suit.class, "", ElementType.FIELD ) );
+ calls.add( new Call(suit, "trousers", Suit.class, "", ElementType.FIELD ) );
+ calls.add( new Call(suit.getTrousers(), "length", Suit.class, "trousers", ElementType.FIELD ) );
+ calls.add( new Call(suit, "jacket", Suit.class, "", ElementType.METHOD ) );
+ calls.add( new Call(suit.getJacket(), "width", Suit.class, "jacket", ElementType.METHOD ) );
+ }
+
+ public Set<String> getPaths() {
+ return paths;
+ }
+
+ //TODO add test with correct paths and types to make sure the impl does not mess it up
+ public boolean isTraversable(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ String path = "";
+ if (! (pathToTraversableObject == null || pathToTraversableObject.length() == 0 ) ) {
+ path = pathToTraversableObject + ".";
+ }
+ paths.add( path + traversableProperty );
+ Call call = new Call(traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType);
+ if ( ! calls.contains( call ) ) {
+
+ throw new IllegalStateException( "Unexpected " + call.toString() );
+ }
+ return true;
+ }
+
+ private static final class Call {
+ private Object traversableObject;
+ private String traversableProperty;
+ private Class<?> rootBeanType;
+ private String pathToTraversableObject;
+ private ElementType elementType;
+
+ private Call(Object traversableObject, String traversableProperty, Class<?> rootBeanType, String pathToTraversableObject, ElementType elementType) {
+ this.traversableObject = traversableObject;
+ this.traversableProperty = traversableProperty;
+ this.rootBeanType = rootBeanType;
+ this.pathToTraversableObject = pathToTraversableObject;
+ this.elementType = elementType;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+
+ Call call = ( Call ) o;
+
+ if ( elementType != call.elementType ) {
+ return false;
+ }
+ if ( !pathToTraversableObject.equals( call.pathToTraversableObject ) ) {
+ return false;
+ }
+ if ( !rootBeanType.equals( call.rootBeanType ) ) {
+ return false;
+ }
+ if ( traversableObject != null ? !(traversableObject == call.traversableObject) : call.traversableObject != null ) {
+ return false;
+ }
+ if ( !traversableProperty.equals( call.traversableProperty ) ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = traversableObject != null ? traversableObject.hashCode() : 0;
+ result = 31 * result + traversableProperty.hashCode();
+ result = 31 * result + rootBeanType.hashCode();
+ result = 31 * result + pathToTraversableObject.hashCode();
+ result = 31 * result + elementType.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "Call{" +
+ "traversableObject=" + traversableObject +
+ ", traversableProperty='" + traversableProperty + '\'' +
+ ", rootBeanType=" + rootBeanType +
+ ", pathToTraversableObject='" + pathToTraversableObject + '\'' +
+ ", elementType=" + elementType +
+ '}';
+ }
+ }
+}
Copied: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/TraversableResolverTest.java (from rev 16497, validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/CachedTraversableResolverTest.java)
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/TraversableResolverTest.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/resolver/TraversableResolverTest.java 2009-05-04 12:42:25 UTC (rev 16505)
@@ -0,0 +1,41 @@
+package org.hibernate.validation.engine.resolver;
+
+import java.lang.annotation.ElementType;
+import java.util.HashSet;
+import java.util.Set;
+import javax.validation.TraversableResolver;
+import javax.validation.Validation;
+import javax.validation.ValidatorFactory;
+import javax.validation.Validator;
+import javax.validation.groups.Default;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+import org.hibernate.validation.engine.HibernateValidatorConfiguration;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class TraversableResolverTest {
+ @Test
+ public void testCorrectPathsAreRequested() {
+ Suit suit = new Suit();
+ suit.setTrousers( new Trousers() );
+ suit.setJacket( new Jacket() );
+ suit.setSize( 3333 );
+ suit.getTrousers().setLength( 32321 );
+ suit.getJacket().setWidth( 432432 );
+
+ SnifferTraversableResolver resolver = new SnifferTraversableResolver(suit);
+ ValidatorFactory factory = Validation.byDefaultProvider()
+ .configure().traversableResolver( resolver )
+ .buildValidatorFactory();
+ Validator v = factory.getValidator();
+
+ //Raises an IllegalStateException if something goes wrong
+ v.validate( suit, Default.class, Cloth.class );
+
+ assertEquals( 5, resolver.getPaths().size() );
+ }
+}
\ No newline at end of file
15 years, 7 months
Hibernate SVN: r16504 - in search/trunk/src: main/java/org/hibernate/search/analyzer and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-05-03 17:41:37 -0400 (Sun, 03 May 2009)
New Revision: 16504
Modified:
search/trunk/src/main/docbook/en-US/modules/mapping.xml
search/trunk/src/main/java/org/hibernate/search/analyzer/Discriminator.java
search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java
search/trunk/src/test/java/org/hibernate/search/test/analyzer/LanguageDiscriminator.java
Log:
HSEARCH-366 : typo in Analyzer Discriminator API
Modified: search/trunk/src/main/docbook/en-US/modules/mapping.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/mapping.xml 2009-05-03 17:21:46 UTC (rev 16503)
+++ search/trunk/src/main/docbook/en-US/modules/mapping.xml 2009-05-03 21:41:37 UTC (rev 16504)
@@ -916,7 +916,7 @@
<programlisting>public class LanguageDiscriminator implements Discriminator {
- public String getAnanyzerDefinitionName(Object value, Object entity, String field) {
+ public String getAnalyzerDefinitionName(Object value, Object entity, String field) {
if ( value == null || !( entity instanceof Article ) ) {
return null;
}
@@ -935,7 +935,7 @@
implementation of the <classname>Discriminator</classname> interface.
It is up to you to provide an implementation for this interface. The
only method you have to implement is
- <classname>getAnanyzerDefinitionName()</classname> which gets called
+ <classname>getAnalyzerDefinitionName()</classname> which gets called
for each field added to the Lucene document. The entity which is
getting indexed is also passed to the interface method. The
<literal>value</literal> parameter is only set if the
Modified: search/trunk/src/main/java/org/hibernate/search/analyzer/Discriminator.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/analyzer/Discriminator.java 2009-05-03 17:21:46 UTC (rev 16503)
+++ search/trunk/src/main/java/org/hibernate/search/analyzer/Discriminator.java 2009-05-03 21:41:37 UTC (rev 16504)
@@ -19,5 +19,5 @@
* default analyzer for this field should be used.
* @see org.hibernate.search.annotations.AnalyzerDef
*/
- String getAnanyzerDefinitionName(Object value, Object entity, String field);
+ String getAnalyzerDefinitionName(Object value, Object entity, String field);
}
Modified: search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java 2009-05-03 17:21:46 UTC (rev 16503)
+++ search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java 2009-05-03 21:41:37 UTC (rev 16504)
@@ -497,7 +497,7 @@
for ( Object o : doc.getFields() ) {
Field field = ( Field ) o;
if ( !processedFieldNames.contains( field.name() ) ) {
- String analyzerName = discriminator.getAnanyzerDefinitionName( value, unproxiedInstance, field.name() );
+ String analyzerName = discriminator.getAnalyzerDefinitionName( value, unproxiedInstance, field.name() );
if ( analyzerName != null ) {
fieldToAnalyzerMap.put( field.name(), analyzerName );
}
Modified: search/trunk/src/test/java/org/hibernate/search/test/analyzer/LanguageDiscriminator.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/analyzer/LanguageDiscriminator.java 2009-05-03 17:21:46 UTC (rev 16503)
+++ search/trunk/src/test/java/org/hibernate/search/test/analyzer/LanguageDiscriminator.java 2009-05-03 21:41:37 UTC (rev 16504)
@@ -8,7 +8,7 @@
*/
public class LanguageDiscriminator implements Discriminator {
- public String getAnanyzerDefinitionName(Object value, Object entity, String field) {
+ public String getAnalyzerDefinitionName(Object value, Object entity, String field) {
if ( value == null || !( entity instanceof Article ) ) {
return null;
}
15 years, 7 months
Hibernate SVN: r16503 - in core/branches/envers-hibernate-3.3/src: main/java/org/hibernate/envers/configuration and 11 other directories.
by hibernate-commits@lists.jboss.org
Author: adamw
Date: 2009-05-03 13:21:46 -0400 (Sun, 03 May 2009)
New Revision: 16503
Added:
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/PrimitiveTestEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/reventity/CustomDataRevEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/primitive/
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/primitive/PrimitiveAddDelete.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/CustomNoListener.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListenerRevEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/TestExceptionRevisionListener.java
Removed:
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/primitive/PrimitiveAddDelete.java
Modified:
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditReader.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SinglePropertyMapper.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/reader/AuditReaderImpl.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/revisioninfo/DefaultRevisionInfoGenerator.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoGenerator.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/synchronization/AuditSync.java
core/branches/envers-hibernate-3.3/src/test/resources/testng.xml
Log:
svn merge -r 16393:16502 https://svn.jboss.org/repos/hibernate/core/trunk/envers .
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditReader.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditReader.java 2009-05-03 13:57:41 UTC (rev 16502)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditReader.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -100,6 +100,20 @@
<T> T findRevision(Class<T> revisionEntityClass, Number revision) throws IllegalArgumentException,
RevisionDoesNotExistException, IllegalStateException;
+ /**
+ * Gets an instance of the current revision entity, to which any entries in the audit tables will be bound.
+ * Please note the if {@code persist} is {@code false}, and no audited entities are modified in this session,
+ * then the obtained revision entity instance won't be persisted. If {@code persist} is {@code true}, the revision
+ * entity instance will always be persisted, regardless of whether audited entities are changed or not.
+ * @param revisionEntityClass Class of the revision entity. Should be annotated with {@link RevisionEntity}.
+ * @param persist If the revision entity is not yet persisted, should it become persisted. This way, the primary
+ * identifier (id) will be filled (if it's assigned by the DB) and available, but the revision entity will be
+ * persisted even if there are no changes to audited entities. Otherwise, the revision number (id) can be
+ * {@code null}.
+ * @return The current revision entity, to which any entries in the audit tables will be bound.
+ */
+ <T> T getCurrentRevision(Class<T> revisionEntityClass, boolean persist);
+
/**
*
* @return A query creator, associated with this AuditReader instance, with which queries can be
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java 2009-05-03 13:57:41 UTC (rev 16502)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/RevisionInfoConfiguration.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -76,11 +76,11 @@
Element idProperty = MetadataTools.addNativelyGeneratedId(class_mapping, revisionInfoIdData.getName(),
revisionPropType);
- MetadataTools.addColumn(idProperty, "REV", null);
+ MetadataTools.addColumn(idProperty, "REV", null, 0, 0, null);
Element timestampProperty = MetadataTools.addProperty(class_mapping, revisionInfoTimestampData.getName(),
revisionInfoTimestampType, true, false);
- MetadataTools.addColumn(timestampProperty, "REVTSTMP", null);
+ MetadataTools.addColumn(timestampProperty, "REVTSTMP", null, 0, 0, null);
return document;
}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java 2009-05-03 13:57:41 UTC (rev 16502)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/AuditMetadataGenerator.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -90,7 +90,7 @@
void addRevisionInfoRelation(Element any_mapping) {
Element rev_mapping = (Element) revisionInfoRelationMapping.clone();
rev_mapping.addAttribute("name", verEntCfg.getRevisionFieldName());
- MetadataTools.addColumn(rev_mapping, verEntCfg.getRevisionFieldName(), null);
+ MetadataTools.addColumn(rev_mapping, verEntCfg.getRevisionFieldName(), null, 0, 0, null);
any_mapping.add(rev_mapping);
}
@@ -197,7 +197,7 @@
Element joinKey = joinElement.addElement("key");
MetadataTools.addColumns(joinKey, join.getKey().getColumnIterator());
- MetadataTools.addColumn(joinKey, verEntCfg.getRevisionFieldName(), null);
+ MetadataTools.addColumn(joinKey, verEntCfg.getRevisionFieldName(), null, 0, 0, null);
}
}
@@ -337,7 +337,7 @@
// Adding the "key" element with all columns + the revision number column
Element keyMapping = mappingData.getFirst().addElement("key");
MetadataTools.addColumns(keyMapping, pc.getIdentifierProperty().getColumnIterator());
- MetadataTools.addColumn(keyMapping, verEntCfg.getRevisionFieldName(), null);
+ MetadataTools.addColumn(keyMapping, verEntCfg.getRevisionFieldName(), null, 0, 0, null);
break;
case TABLE_PER_CLASS:
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java 2009-05-03 13:57:41 UTC (rev 16502)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/MetadataTools.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -68,13 +68,23 @@
return prop_mapping;
}
- public static Element addColumn(Element parent, String name, Integer length) {
+ public static Element addColumn(Element parent, String name, Integer length, Integer scale, Integer precision,
+ String sqlType) {
Element column_mapping = parent.addElement("column");
column_mapping.addAttribute("name", name);
if (length != null) {
column_mapping.addAttribute("length", length.toString());
}
+ if (scale != 0) {
+ column_mapping.addAttribute("scale", Integer.toString(scale));
+ }
+ if (precision != 0) {
+ column_mapping.addAttribute("precision", Integer.toString(precision));
+ }
+ if (sqlType != null) {
+ column_mapping.addAttribute("sql-type", sqlType);
+ }
return column_mapping;
}
@@ -142,7 +152,8 @@
public static void addColumns(Element any_mapping, Iterator<Column> columns) {
while (columns.hasNext()) {
Column column = columns.next();
- addColumn(any_mapping, column.getName(), column.getLength());
+ addColumn(any_mapping, column.getName(), column.getLength(), column.getScale(), column.getPrecision(),
+ column.getSqlType());
}
}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SinglePropertyMapper.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SinglePropertyMapper.java 2009-05-03 13:57:41 UTC (rev 16502)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SinglePropertyMapper.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -36,7 +36,9 @@
import org.hibernate.collection.PersistentCollection;
import org.hibernate.property.Setter;
+import org.hibernate.property.DirectPropertyAccessor;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.HibernateException;
/**
* TODO: diff
@@ -68,9 +70,27 @@
}
Setter setter = ReflectionTools.getSetter(obj.getClass(), propertyData);
- setter.set(obj, data.get(propertyData.getName()), null);
+ Object value = data.get(propertyData.getName());
+ // We only set a null value if the field is not primite. Otherwise, we leave it intact.
+ if (value != null || !isPrimitive(setter, propertyData, obj.getClass())) {
+ setter.set(obj, value, null);
+ }
}
+ private boolean isPrimitive(Setter setter, PropertyData propertyData, Class<?> cls) {
+ if (setter instanceof DirectPropertyAccessor.DirectSetter) {
+ // In a direct setter, getMethod() returns null
+ // Trying to look up the field
+ try {
+ return cls.getDeclaredField(propertyData.getBeanName()).getType().isPrimitive();
+ } catch (NoSuchFieldException e) {
+ throw new HibernateException(e);
+ }
+ } else {
+ return setter.getMethod().getParameterTypes()[0].isPrimitive();
+ }
+ }
+
public List<PersistentCollectionChangeData> mapCollectionChanges(String referencingPropertyName,
PersistentCollection newColl,
Serializable oldColl,
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/reader/AuditReaderImpl.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/reader/AuditReaderImpl.java 2009-05-03 13:57:41 UTC (rev 16502)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/reader/AuditReaderImpl.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -34,10 +34,12 @@
import org.hibernate.envers.query.AuditEntity;
import static org.hibernate.envers.tools.ArgumentsTools.checkNotNull;
import static org.hibernate.envers.tools.ArgumentsTools.checkPositive;
+import org.hibernate.envers.synchronization.AuditSync;
import org.hibernate.NonUniqueResultException;
import org.hibernate.Query;
import org.hibernate.Session;
+import org.hibernate.event.EventSource;
import org.hibernate.engine.SessionImplementor;
import org.jboss.envers.query.VersionsQueryCreator;
@@ -190,7 +192,20 @@
}
}
- public VersionsQueryCreator createQuery() {
+ @SuppressWarnings({"unchecked"})
+ public <T> T getCurrentRevision(Class<T> revisionEntityClass, boolean persist) {
+ if (!(session instanceof EventSource)) {
+ throw new IllegalArgumentException("The provided session is not an EventSource!");
+ }
+
+ // Obtaining the current audit sync
+ AuditSync auditSync = verCfg.getSyncManager().get((EventSource) session);
+
+ // And getting the current revision data
+ return (T) auditSync.getCurrentRevisionData(session, persist);
+ }
+
+ public VersionsQueryCreator createQuery() {
return new VersionsQueryCreator(verCfg, this);
}
}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/revisioninfo/DefaultRevisionInfoGenerator.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/revisioninfo/DefaultRevisionInfoGenerator.java 2009-05-03 13:57:41 UTC (rev 16502)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/revisioninfo/DefaultRevisionInfoGenerator.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -63,14 +63,18 @@
}
}
- private Object newRevision() {
- Object revisionInfo;
+ public void saveRevisionData(Session session, Object revisionData) {
+ session.save(revisionInfoEntityName, revisionData);
+ }
+
+ public Object generate() {
+ Object revisionInfo;
try {
revisionInfo = revisionInfoClass.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
-
+
revisionTimestampSetter.set(revisionInfo, System.currentTimeMillis(), null);
if (listener != null) {
@@ -79,10 +83,4 @@
return revisionInfo;
}
-
- public Object generate(Session session) {
- Object revisionData = newRevision();
- session.save(revisionInfoEntityName, revisionData);
- return revisionData;
- }
}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoGenerator.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoGenerator.java 2009-05-03 13:57:41 UTC (rev 16502)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/revisioninfo/RevisionInfoGenerator.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -29,5 +29,6 @@
* @author Adam Warski (adam at warski dot org)
*/
public interface RevisionInfoGenerator {
- Object generate(Session session);
+ void saveRevisionData(Session session, Object revisionData);
+ Object generate();
}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/synchronization/AuditSync.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/synchronization/AuditSync.java 2009-05-03 13:57:41 UTC (rev 16502)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/synchronization/AuditSync.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -111,9 +111,8 @@
}
private void executeInSession(Session session) {
- if (revisionData == null) {
- revisionData = revisionInfoGenerator.generate(session);
- }
+ // Making sure the revision data is persisted.
+ getCurrentRevisionData(session, true);
AuditWorkUnit vwu;
@@ -127,31 +126,51 @@
}
}
+ public Object getCurrentRevisionData(Session session, boolean persist) {
+ // Generating the revision data if not yet generated
+ if (revisionData == null) {
+ revisionData = revisionInfoGenerator.generate();
+ }
+
+ // Saving the revision data, if not yet saved and persist is true
+ if (!session.contains(revisionData) && persist) {
+ revisionInfoGenerator.saveRevisionData(session, revisionData);
+ }
+
+ return revisionData;
+ }
+
public void beforeCompletion() {
if (workUnits.size() == 0 && undoQueue.size() == 0) {
return;
}
- // see: http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4178431
- if (FlushMode.isManualFlushMode(session.getFlushMode()) || session.isClosed()) {
- Session temporarySession = null;
- try {
- temporarySession = session.getFactory().openTemporarySession();
+ try {
+ // see: http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4178431
+ if (FlushMode.isManualFlushMode(session.getFlushMode()) || session.isClosed()) {
+ Session temporarySession = null;
+ try {
+ temporarySession = session.getFactory().openTemporarySession();
- executeInSession(temporarySession);
+ executeInSession(temporarySession);
- temporarySession.flush();
- } finally {
- if (temporarySession != null) {
- temporarySession.close();
- }
- }
- } else {
- executeInSession(session);
+ temporarySession.flush();
+ } finally {
+ if (temporarySession != null) {
+ temporarySession.close();
+ }
+ }
+ } else {
+ executeInSession(session);
- // Explicity flushing the session, as the auto-flush may have already happened.
- session.flush();
- }
+ // Explicity flushing the session, as the auto-flush may have already happened.
+ session.flush();
+ }
+ } catch (RuntimeException e) {
+ // Rolling back the transaction in case of any exceptions
+ session.getTransaction().rollback();
+ throw e;
+ }
}
public void afterCompletion(int i) {
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/PrimitiveTestEntity.java (from rev 16502, core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/PrimitiveTestEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/PrimitiveTestEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/PrimitiveTestEntity.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -0,0 +1,109 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.entities;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.envers.Audited;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+public class PrimitiveTestEntity {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ @Audited
+ private int number;
+
+ private int number2;
+
+ public PrimitiveTestEntity() {
+ }
+
+ public PrimitiveTestEntity(int number, int number2) {
+ this.number = number;
+ this.number2 = number2;
+ }
+
+ public PrimitiveTestEntity(Integer id, int number, int number2) {
+ this.id = id;
+ this.number = number;
+ this.number2 = number2;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public Integer getNumber() {
+ return number;
+ }
+
+ public void setNumber(Integer number) {
+ this.number = number;
+ }
+
+ public int getNumber2() {
+ return number2;
+ }
+
+ public void setNumber2(int number2) {
+ this.number2 = number2;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof PrimitiveTestEntity)) return false;
+
+ PrimitiveTestEntity that = (PrimitiveTestEntity) o;
+
+ if (number != that.number) return false;
+ if (number2 != that.number2) return false;
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id != null ? id.hashCode() : 0;
+ result = 31 * result + number;
+ result = 31 * result + number2;
+ return result;
+ }
+
+ public String toString() {
+ return "PTE(id = " + id + ", number = " + number + ", number2 = " + number2 + ")";
+ }
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/reventity/CustomDataRevEntity.java (from rev 16502, core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/reventity/CustomDataRevEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/reventity/CustomDataRevEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/reventity/CustomDataRevEntity.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -0,0 +1,95 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.entities.reventity;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.envers.RevisionEntity;
+import org.hibernate.envers.RevisionNumber;
+import org.hibernate.envers.RevisionTimestamp;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+@RevisionEntity
+public class CustomDataRevEntity {
+ @Id
+ @GeneratedValue
+ @RevisionNumber
+ private int customId;
+
+ @RevisionTimestamp
+ private long customTimestamp;
+
+ private String data;
+
+ public int getCustomId() {
+ return customId;
+ }
+
+ public void setCustomId(int customId) {
+ this.customId = customId;
+ }
+
+ public long getCustomTimestamp() {
+ return customTimestamp;
+ }
+
+ public void setCustomTimestamp(long customTimestamp) {
+ this.customTimestamp = customTimestamp;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof CustomDataRevEntity)) return false;
+
+ CustomDataRevEntity that = (CustomDataRevEntity) o;
+
+ if (customId != that.customId) return false;
+ if (customTimestamp != that.customTimestamp) return false;
+ if (data != null ? !data.equals(that.data) : that.data != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = customId;
+ result = 31 * result + (int) (customTimestamp ^ (customTimestamp >>> 32));
+ result = 31 * result + (data != null ? data.hashCode() : 0);
+ return result;
+ }
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/primitive (from rev 16502, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/primitive)
Deleted: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/primitive/PrimitiveAddDelete.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/primitive/PrimitiveAddDelete.java 2009-05-03 13:57:41 UTC (rev 16502)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/primitive/PrimitiveAddDelete.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -1,97 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.envers.test.integration.primitive;
-
-import java.util.Arrays;
-import java.util.List;
-import javax.persistence.EntityManager;
-
-import org.hibernate.envers.test.AbstractEntityTest;
-import org.hibernate.envers.test.entities.PrimitiveTestEntity;
-import org.testng.annotations.Test;
-
-import org.hibernate.ejb.Ejb3Configuration;
-
-/**
- * @author Adam Warski (adam at warski dot org)
- */
-public class PrimitiveAddDelete extends AbstractEntityTest {
- private Integer id1;
-
- public void configure(Ejb3Configuration cfg) {
- cfg.addAnnotatedClass(PrimitiveTestEntity.class);
- }
-
- @Test
- public void initData() {
- EntityManager em = getEntityManager();
-
- // Revision 1
- em.getTransaction().begin();
- PrimitiveTestEntity pte = new PrimitiveTestEntity(10, 11);
- em.persist(pte);
- id1 = pte.getId();
- em.getTransaction().commit();
-
- // Revision 2
- em.getTransaction().begin();
- pte = em.find(PrimitiveTestEntity.class, id1);
- pte.setNumber(20);
- pte.setNumber2(21);
- em.getTransaction().commit();
-
- // Revision 3
- em.getTransaction().begin();
- pte = em.find(PrimitiveTestEntity.class, id1);
- em.remove(pte);
- em.getTransaction().commit();
- }
-
- @Test(dependsOnMethods = "initData")
- public void testRevisionsCounts() {
- assert Arrays.asList(1, 2, 3).equals(getAuditReader().getRevisions(PrimitiveTestEntity.class, id1));
- }
-
- @Test(dependsOnMethods = "initData")
- public void testHistoryOfId1() {
- PrimitiveTestEntity ver1 = new PrimitiveTestEntity(id1, 10, 0);
- PrimitiveTestEntity ver2 = new PrimitiveTestEntity(id1, 20, 0);
-
- assert getAuditReader().find(PrimitiveTestEntity.class, id1, 1).equals(ver1);
- assert getAuditReader().find(PrimitiveTestEntity.class, id1, 2).equals(ver2);
- assert getAuditReader().find(PrimitiveTestEntity.class, id1, 3) == null;
- }
-
- @Test(dependsOnMethods = "initData")
- public void testQueryWithDeleted() {
- // Selecting all entities, also the deleted ones
- List entities = getAuditReader().createQuery().forRevisionsOfEntity(PrimitiveTestEntity.class, true, true)
- .getResultList();
-
- assert entities.size() == 3;
- assert entities.get(0).equals(new PrimitiveTestEntity(id1, 10, 0));
- assert entities.get(1).equals(new PrimitiveTestEntity(id1, 20, 0));
- assert entities.get(2).equals(new PrimitiveTestEntity(id1, 0, 0));
- }
-}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/primitive/PrimitiveAddDelete.java (from rev 16502, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/primitive/PrimitiveAddDelete.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/primitive/PrimitiveAddDelete.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/primitive/PrimitiveAddDelete.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -0,0 +1,97 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.primitive;
+
+import java.util.Arrays;
+import java.util.List;
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.PrimitiveTestEntity;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class PrimitiveAddDelete extends AbstractEntityTest {
+ private Integer id1;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(PrimitiveTestEntity.class);
+ }
+
+ @Test
+ public void initData() {
+ EntityManager em = getEntityManager();
+
+ // Revision 1
+ em.getTransaction().begin();
+ PrimitiveTestEntity pte = new PrimitiveTestEntity(10, 11);
+ em.persist(pte);
+ id1 = pte.getId();
+ em.getTransaction().commit();
+
+ // Revision 2
+ em.getTransaction().begin();
+ pte = em.find(PrimitiveTestEntity.class, id1);
+ pte.setNumber(20);
+ pte.setNumber2(21);
+ em.getTransaction().commit();
+
+ // Revision 3
+ em.getTransaction().begin();
+ pte = em.find(PrimitiveTestEntity.class, id1);
+ em.remove(pte);
+ em.getTransaction().commit();
+ }
+
+ @Test(dependsOnMethods = "initData")
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1, 2, 3).equals(getAuditReader().getRevisions(PrimitiveTestEntity.class, id1));
+ }
+
+ @Test(dependsOnMethods = "initData")
+ public void testHistoryOfId1() {
+ PrimitiveTestEntity ver1 = new PrimitiveTestEntity(id1, 10, 0);
+ PrimitiveTestEntity ver2 = new PrimitiveTestEntity(id1, 20, 0);
+
+ assert getAuditReader().find(PrimitiveTestEntity.class, id1, 1).equals(ver1);
+ assert getAuditReader().find(PrimitiveTestEntity.class, id1, 2).equals(ver2);
+ assert getAuditReader().find(PrimitiveTestEntity.class, id1, 3) == null;
+ }
+
+ @Test(dependsOnMethods = "initData")
+ public void testQueryWithDeleted() {
+ // Selecting all entities, also the deleted ones
+ List entities = getAuditReader().createQuery().forRevisionsOfEntity(PrimitiveTestEntity.class, true, true)
+ .getResultList();
+
+ assert entities.size() == 3;
+ assert entities.get(0).equals(new PrimitiveTestEntity(id1, 10, 0));
+ assert entities.get(1).equals(new PrimitiveTestEntity(id1, 20, 0));
+ assert entities.get(2).equals(new PrimitiveTestEntity(id1, 0, 0));
+ }
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/CustomNoListener.java (from rev 16502, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/CustomNoListener.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/CustomNoListener.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/CustomNoListener.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -0,0 +1,137 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.reventity;
+
+import java.util.Arrays;
+import java.util.Date;
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.AuditReader;
+import org.hibernate.envers.exception.RevisionDoesNotExistException;
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.StrTestEntity;
+import org.hibernate.envers.test.entities.reventity.CustomDataRevEntity;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class CustomNoListener extends AbstractEntityTest {
+ private Integer id;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(StrTestEntity.class);
+ cfg.addAnnotatedClass(CustomDataRevEntity.class);
+ }
+
+ @BeforeClass(dependsOnMethods = "init")
+ public void initData() throws InterruptedException {
+ EntityManager em = getEntityManager();
+
+ // Revision 1
+ em.getTransaction().begin();
+ StrTestEntity te = new StrTestEntity("x");
+ em.persist(te);
+ id = te.getId();
+
+ // Setting the data on the revision entity
+ CustomDataRevEntity custom = getAuditReader().getCurrentRevision(CustomDataRevEntity.class, false);
+ custom.setData("data1");
+
+ em.getTransaction().commit();
+
+ // Revision 2
+ em.getTransaction().begin();
+ te = em.find(StrTestEntity.class, id);
+ te.setStr("y");
+
+ // Setting the data on the revision entity
+ custom = getAuditReader().getCurrentRevision(CustomDataRevEntity.class, false);
+ custom.setData("data2");
+
+ em.getTransaction().commit();
+
+ // Revision 3 - no changes, but rev entity should be persisted
+ em.getTransaction().begin();
+
+ // Setting the data on the revision entity
+ custom = getAuditReader().getCurrentRevision(CustomDataRevEntity.class, true);
+ custom.setData("data3");
+
+ em.getTransaction().commit();
+
+ // No changes, rev entity won't be persisted
+ em.getTransaction().begin();
+
+ // Setting the data on the revision entity
+ custom = getAuditReader().getCurrentRevision(CustomDataRevEntity.class, false);
+ custom.setData("data4");
+
+ em.getTransaction().commit();
+
+ // Revision 4
+ em.getTransaction().begin();
+ te = em.find(StrTestEntity.class, id);
+ te.setStr("z");
+
+ // Setting the data on the revision entity
+ custom = getAuditReader().getCurrentRevision(CustomDataRevEntity.class, false);
+ custom.setData("data5");
+
+ custom = getAuditReader().getCurrentRevision(CustomDataRevEntity.class, false);
+ custom.setData("data5bis");
+
+ em.getTransaction().commit();
+ }
+
+ @Test
+ public void testFindRevision() {
+ AuditReader vr = getAuditReader();
+
+ assert "data1".equals(vr.findRevision(CustomDataRevEntity.class, 1).getData());
+ assert "data2".equals(vr.findRevision(CustomDataRevEntity.class, 2).getData());
+ assert "data3".equals(vr.findRevision(CustomDataRevEntity.class, 3).getData());
+ assert "data5bis".equals(vr.findRevision(CustomDataRevEntity.class, 4).getData());
+ }
+
+ @Test
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1, 2, 4).equals(getAuditReader().getRevisions(StrTestEntity.class, id));
+ }
+
+ @Test
+ public void testHistoryOfId1() {
+ StrTestEntity ver1 = new StrTestEntity("x", id);
+ StrTestEntity ver2 = new StrTestEntity("y", id);
+ StrTestEntity ver3 = new StrTestEntity("z", id);
+
+ assert getAuditReader().find(StrTestEntity.class, id, 1).equals(ver1);
+ assert getAuditReader().find(StrTestEntity.class, id, 2).equals(ver2);
+ assert getAuditReader().find(StrTestEntity.class, id, 3).equals(ver2);
+ assert getAuditReader().find(StrTestEntity.class, id, 4).equals(ver3);
+ }
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java (from rev 16502, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -0,0 +1,60 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.reventity;
+
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.StrTestEntity;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class ExceptionListener extends AbstractEntityTest {
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(StrTestEntity.class);
+ cfg.addAnnotatedClass(ExceptionListenerRevEntity.class);
+ }
+
+ @Test
+ public void testTransactionRollback() throws InterruptedException {
+ // Trying to persist an entity - however the listener should throw an exception, so the entity
+ // shouldn't be persisted
+ EntityManager em = getEntityManager();
+ em.getTransaction().begin();
+ StrTestEntity te = new StrTestEntity("x");
+ em.persist(te);
+ em.getTransaction().commit();
+
+ // Checking if the entity became persisted
+ em = getEntityManager();
+ em.getTransaction().begin();
+ Long count = (Long) em.createQuery("select count(s) from StrTestEntity s where s.str = 'x'").getSingleResult();
+ assert count == 0l;
+ em.getTransaction().commit();
+ }
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListenerRevEntity.java (from rev 16502, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListenerRevEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListenerRevEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListenerRevEntity.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -0,0 +1,82 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.reventity;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.envers.RevisionEntity;
+import org.hibernate.envers.RevisionNumber;
+import org.hibernate.envers.RevisionTimestamp;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+(a)RevisionEntity(TestExceptionRevisionListener.class)
+public class ExceptionListenerRevEntity {
+ @Id
+ @GeneratedValue
+ @RevisionNumber
+ private int id;
+
+ @RevisionTimestamp
+ private long timestamp;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ExceptionListenerRevEntity)) return false;
+
+ ExceptionListenerRevEntity revEntity = (ExceptionListenerRevEntity) o;
+
+ if (id != revEntity.id) return false;
+ if (timestamp != revEntity.timestamp) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = id;
+ result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
+ return result;
+ }
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/TestExceptionRevisionListener.java (from rev 16502, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/TestExceptionRevisionListener.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/TestExceptionRevisionListener.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/reventity/TestExceptionRevisionListener.java 2009-05-03 17:21:46 UTC (rev 16503)
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.reventity;
+
+import org.hibernate.envers.RevisionListener;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class TestExceptionRevisionListener implements RevisionListener {
+ public void newRevision(Object revisionEntity) {
+ throw new RuntimeException();
+ }
+}
\ No newline at end of file
Modified: core/branches/envers-hibernate-3.3/src/test/resources/testng.xml
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/resources/testng.xml 2009-05-03 13:57:41 UTC (rev 16502)
+++ core/branches/envers-hibernate-3.3/src/test/resources/testng.xml 2009-05-03 17:21:46 UTC (rev 16503)
@@ -42,6 +42,7 @@
<package name="org.hibernate.envers.test.integration.onetoone.bidirectional" />
<package name="org.hibernate.envers.test.integration.onetoone.bidirectional.ids" />
<package name="org.hibernate.envers.test.integration.onetoone.unidirectional" />
+ <package name="org.hibernate.envers.test.integration.primitive" />
<package name="org.hibernate.envers.test.integration.properties" />
<package name="org.hibernate.envers.test.integration.query" />
<package name="org.hibernate.envers.test.integration.query.ids" />
15 years, 7 months
Hibernate SVN: r16502 - in core/trunk/envers/src: test/java/org/hibernate/envers/test/integration/reventity and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: adamw
Date: 2009-05-03 09:57:41 -0400 (Sun, 03 May 2009)
New Revision: 16502
Added:
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListenerRevEntity.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/TestExceptionRevisionListener.java
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSync.java
Log:
Rolling back the TX when an exception occures in a revision listener
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSync.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSync.java 2009-05-01 23:21:00 UTC (rev 16501)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/AuditSync.java 2009-05-03 13:57:41 UTC (rev 16502)
@@ -145,26 +145,32 @@
return;
}
- // see: http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4178431
- if (FlushMode.isManualFlushMode(session.getFlushMode()) || session.isClosed()) {
- Session temporarySession = null;
- try {
- temporarySession = session.getFactory().openTemporarySession();
+ try {
+ // see: http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4178431
+ if (FlushMode.isManualFlushMode(session.getFlushMode()) || session.isClosed()) {
+ Session temporarySession = null;
+ try {
+ temporarySession = session.getFactory().openTemporarySession();
- executeInSession(temporarySession);
+ executeInSession(temporarySession);
- temporarySession.flush();
- } finally {
- if (temporarySession != null) {
- temporarySession.close();
- }
- }
- } else {
- executeInSession(session);
+ temporarySession.flush();
+ } finally {
+ if (temporarySession != null) {
+ temporarySession.close();
+ }
+ }
+ } else {
+ executeInSession(session);
- // Explicity flushing the session, as the auto-flush may have already happened.
- session.flush();
- }
+ // Explicity flushing the session, as the auto-flush may have already happened.
+ session.flush();
+ }
+ } catch (RuntimeException e) {
+ // Rolling back the transaction in case of any exceptions
+ session.getTransaction().rollback();
+ throw e;
+ }
}
public void afterCompletion(int i) {
Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java (from rev 16487, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/Listener.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListener.java 2009-05-03 13:57:41 UTC (rev 16502)
@@ -0,0 +1,60 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.reventity;
+
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.StrTestEntity;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class ExceptionListener extends AbstractEntityTest {
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(StrTestEntity.class);
+ cfg.addAnnotatedClass(ExceptionListenerRevEntity.class);
+ }
+
+ @Test
+ public void testTransactionRollback() throws InterruptedException {
+ // Trying to persist an entity - however the listener should throw an exception, so the entity
+ // shouldn't be persisted
+ EntityManager em = getEntityManager();
+ em.getTransaction().begin();
+ StrTestEntity te = new StrTestEntity("x");
+ em.persist(te);
+ em.getTransaction().commit();
+
+ // Checking if the entity became persisted
+ em = getEntityManager();
+ em.getTransaction().begin();
+ Long count = (Long) em.createQuery("select count(s) from StrTestEntity s where s.str = 'x'").getSingleResult();
+ assert count == 0l;
+ em.getTransaction().commit();
+ }
+}
\ No newline at end of file
Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListenerRevEntity.java (from rev 16487, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ListenerRevEntity.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListenerRevEntity.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/ExceptionListenerRevEntity.java 2009-05-03 13:57:41 UTC (rev 16502)
@@ -0,0 +1,82 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.reventity;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.envers.RevisionEntity;
+import org.hibernate.envers.RevisionNumber;
+import org.hibernate.envers.RevisionTimestamp;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+(a)RevisionEntity(TestExceptionRevisionListener.class)
+public class ExceptionListenerRevEntity {
+ @Id
+ @GeneratedValue
+ @RevisionNumber
+ private int id;
+
+ @RevisionTimestamp
+ private long timestamp;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ExceptionListenerRevEntity)) return false;
+
+ ExceptionListenerRevEntity revEntity = (ExceptionListenerRevEntity) o;
+
+ if (id != revEntity.id) return false;
+ if (timestamp != revEntity.timestamp) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = id;
+ result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
+ return result;
+ }
+}
\ No newline at end of file
Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/TestExceptionRevisionListener.java (from rev 16487, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/TestRevisionListener.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/TestExceptionRevisionListener.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/reventity/TestExceptionRevisionListener.java 2009-05-03 13:57:41 UTC (rev 16502)
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.reventity;
+
+import org.hibernate.envers.RevisionListener;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class TestExceptionRevisionListener implements RevisionListener {
+ public void newRevision(Object revisionEntity) {
+ throw new RuntimeException();
+ }
+}
\ No newline at end of file
15 years, 7 months
Hibernate SVN: r16501 - in core/trunk: core/src/main/java/org/hibernate/dialect and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: gbadner
Date: 2009-05-01 19:21:00 -0400 (Fri, 01 May 2009)
New Revision: 16501
Added:
core/trunk/core/src/main/java/org/hibernate/type/AbstractLongBinaryType.java
core/trunk/core/src/main/java/org/hibernate/type/AbstractLongStringType.java
core/trunk/core/src/main/java/org/hibernate/type/ImageType.java
core/trunk/core/src/main/java/org/hibernate/type/MaterializedBlobType.java
core/trunk/core/src/main/java/org/hibernate/type/MaterializedClobType.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ClobLocatorTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ImageMappings.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ImageTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayHolder.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongStringHolder.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongStringTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobMappings.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobMappings.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableHolder.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableMappings.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/TextMappings.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/TextTest.java
Removed:
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/BlobTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ClobTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobType.java
Modified:
core/trunk/core/src/main/java/org/hibernate/Hibernate.java
core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/MySQLDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java
core/trunk/core/src/main/java/org/hibernate/type/TextType.java
core/trunk/core/src/main/java/org/hibernate/type/TypeFactory.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LobHolder.java
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LobMappings.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableTypeTest.java
Log:
HHH-3892 : Improve support for mapping SQL LONGVARCHAR and CLOB to Java String, SQL LONGVARBINARY and BLOB to Java byte[]
Modified: core/trunk/core/src/main/java/org/hibernate/Hibernate.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Hibernate.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/core/src/main/java/org/hibernate/Hibernate.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -79,6 +79,9 @@
import org.hibernate.type.CharArrayType;
import org.hibernate.type.WrapperBinaryType;
import org.hibernate.type.CharacterArrayType;
+import org.hibernate.type.MaterializedBlobType;
+import org.hibernate.type.ImageType;
+import org.hibernate.type.MaterializedClobType;
import org.hibernate.usertype.CompositeUserType;
/**
@@ -178,10 +181,22 @@
*/
public static final NullableType CHARACTER_ARRAY = new CharacterArrayType();
/**
+ * Hibernate <tt>image</tt> type.
+ */
+ public static final NullableType IMAGE = new ImageType();
+ /**
* Hibernate <tt>text</tt> type.
*/
public static final NullableType TEXT = new TextType();
/**
+ * Hibernate <tt>materialized_blob</tt> type.
+ */
+ public static final NullableType MATERIALIZED_BLOB = new MaterializedBlobType();
+ /**
+ * Hibernate <tt>materialized_clob</tt> type.
+ */
+ public static final NullableType MATERIALIZED_CLOB = new MaterializedClobType();
+ /**
* Hibernate <tt>blob</tt> type.
*/
public static final Type BLOB = new BlobType();
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -61,6 +61,8 @@
registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
registerColumnType( Types.BLOB, "blob($l)" );
registerColumnType( Types.CLOB, "clob($l)" );
+ registerColumnType( Types.LONGVARCHAR, "long varchar" );
+ registerColumnType( Types.LONGVARBINARY, "long varchar for bit data" );
registerFunction("abs", new StandardSQLFunction("abs") );
registerFunction("absval", new StandardSQLFunction("absval") );
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -81,6 +81,8 @@
//HSQL has no Blob/Clob support .... but just put these here for now!
registerColumnType( Types.BLOB, "longvarbinary" );
registerColumnType( Types.CLOB, "longvarchar" );
+ registerColumnType( Types.LONGVARBINARY, "longvarbinary" );
+ registerColumnType( Types.LONGVARCHAR, "longvarchar" );
registerFunction( "ascii", new StandardSQLFunction( "ascii", Hibernate.INTEGER ) );
registerFunction( "char", new StandardSQLFunction( "char", Hibernate.CHARACTER ) );
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -36,5 +36,6 @@
registerColumnType( Types.VARCHAR, "longtext" );
// registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
registerColumnType( Types.VARCHAR, 65535, "varchar($l)" );
+ registerColumnType( Types.LONGVARCHAR, "longtext" );
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/MySQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/MySQLDialect.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/MySQLDialect.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -59,6 +59,8 @@
registerColumnType( Types.VARBINARY, 16777215, "mediumblob" );
registerColumnType( Types.VARBINARY, 65535, "blob" );
registerColumnType( Types.VARBINARY, 255, "tinyblob" );
+ registerColumnType( Types.LONGVARBINARY, "longblob" );
+ registerColumnType( Types.LONGVARBINARY, 16777215, "mediumblob" );
registerColumnType( Types.NUMERIC, "decimal($p,$s)" );
registerColumnType( Types.BLOB, "longblob" );
// registerColumnType( Types.BLOB, 16777215, "mediumblob" );
@@ -181,6 +183,7 @@
// registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
// registerColumnType( Types.VARCHAR, 65535, "text" );
registerColumnType( Types.VARCHAR, 255, "varchar($l)" );
+ registerColumnType( Types.LONGVARCHAR, "longtext" );
}
public String getAddColumnString() {
@@ -344,4 +347,4 @@
public boolean supportsSubqueryOnMutatingTable() {
return false;
}
-}
\ No newline at end of file
+}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -98,6 +98,9 @@
registerColumnType( Types.BLOB, "blob" );
registerColumnType( Types.CLOB, "clob" );
+
+ registerColumnType( Types.LONGVARCHAR, "long" );
+ registerColumnType( Types.LONGVARBINARY, "long raw" );
}
protected void registerReverseHibernateTypeMappings() {
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -62,6 +62,8 @@
registerColumnType( Types.TIME, "time" );
registerColumnType( Types.TIMESTAMP, "timestamp" );
registerColumnType( Types.VARBINARY, "bytea" );
+ registerColumnType( Types.LONGVARCHAR, "text" );
+ registerColumnType( Types.LONGVARBINARY, "bytea" );
registerColumnType( Types.CLOB, "text" );
registerColumnType( Types.BLOB, "oid" );
registerColumnType( Types.NUMERIC, "numeric($p, $s)" );
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -42,6 +42,8 @@
public SQLServerDialect() {
registerColumnType( Types.VARBINARY, "image" );
registerColumnType( Types.VARBINARY, 8000, "varbinary($l)" );
+ registerColumnType( Types.LONGVARBINARY, "image" );
+ registerColumnType( Types.LONGVARCHAR, "text" );
registerFunction( "second", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(second, ?1)" ) );
registerFunction( "minute", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(minute, ?1)" ) );
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/SybaseASE15Dialect.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -50,6 +50,10 @@
public class SybaseASE15Dialect extends AbstractTransactSQLDialect {
public SybaseASE15Dialect() {
super();
+
+ registerColumnType( Types.LONGVARBINARY, "image" );
+ registerColumnType( Types.LONGVARCHAR, "text" );
+
registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(second, ?1)") );
registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(minute, ?1)") );
registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(hour, ?1)") );
Added: core/trunk/core/src/main/java/org/hibernate/type/AbstractLongBinaryType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/AbstractLongBinaryType.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/type/AbstractLongBinaryType.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,46 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.type;
+
+/**
+ * An abstract type for mapping long binary SQL types to Java byte[].
+ *
+ * @author Gail Badner
+ */
+public abstract class AbstractLongBinaryType extends AbstractBynaryType {
+
+ public Class getReturnedClass() {
+ return byte[].class;
+ }
+
+ protected Object toExternalFormat(byte[] bytes) {
+ return bytes;
+ }
+
+ protected byte[] toInternalFormat(Object bytes) {
+ return ( byte[] ) bytes;
+ }
+}
\ No newline at end of file
Added: core/trunk/core/src/main/java/org/hibernate/type/AbstractLongStringType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/AbstractLongStringType.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/type/AbstractLongStringType.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,94 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.type;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+
+/**
+ * An abstract type for mapping long string SQL types to a Java String.
+ * @author Gavin King, Bertrand Renuart (from TextType)
+ */
+public abstract class AbstractLongStringType extends ImmutableType {
+
+ public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ String str = (String) value;
+ st.setCharacterStream( index, new StringReader(str), str.length() );
+ }
+
+ public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+
+ // Retrieve the value of the designated column in the current row of this
+ // ResultSet object as a java.io.Reader object
+ Reader charReader = rs.getCharacterStream(name);
+
+ // if the corresponding SQL value is NULL, the reader we got is NULL as well
+ if (charReader==null) return null;
+
+ // Fetch Reader content up to the end - and put characters in a StringBuffer
+ StringBuffer sb = new StringBuffer();
+ try {
+ char[] buffer = new char[2048];
+ while (true) {
+ int amountRead = charReader.read(buffer, 0, buffer.length);
+ if ( amountRead == -1 ) break;
+ sb.append(buffer, 0, amountRead);
+ }
+ }
+ catch (IOException ioe) {
+ throw new HibernateException( "IOException occurred reading text", ioe );
+ }
+ finally {
+ try {
+ charReader.close();
+ }
+ catch (IOException e) {
+ throw new HibernateException( "IOException occurred closing stream", e );
+ }
+ }
+
+ // Return StringBuffer content as a large String
+ return sb.toString();
+ }
+
+ public Class getReturnedClass() {
+ return String.class;
+ }
+
+ public String toString(Object val) {
+ return (String) val;
+ }
+ public Object fromStringValue(String xml) {
+ return xml;
+ }
+
+}
\ No newline at end of file
Added: core/trunk/core/src/main/java/org/hibernate/type/ImageType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ImageType.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/type/ImageType.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,44 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.type;
+
+import java.sql.Types;
+
+/**
+ * <tt>image</tt>: A type that maps an SQL LONGVARBINARY to Java byte[].
+ *
+ * @author Gail Badner
+ */
+public class ImageType extends AbstractLongBinaryType {
+
+ public int sqlType() {
+ return Types.LONGVARBINARY;
+ }
+
+ public String getName() {
+ return "image";
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/type/MaterializedBlobType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/MaterializedBlobType.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/type/MaterializedBlobType.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,44 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.type;
+
+import java.sql.Types;
+
+/**
+ * <tt>materialized_blob</tt>: A type that maps an SQL BLOB to Java byte[].
+ *
+ * @author Gail Badner
+ */
+public class MaterializedBlobType extends AbstractLongBinaryType {
+
+ public int sqlType() {
+ return Types.BLOB;
+ }
+
+ public String getName() {
+ return "materialized_blob";
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/type/MaterializedClobType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/MaterializedClobType.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/type/MaterializedClobType.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,42 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.type;
+
+import java.sql.Types;
+
+/**
+ * <tt>materialized_clob</tt>: A type that maps an SQL CLOB to a Java String.
+ *
+ * @author Gail Badner
+ */
+public class MaterializedClobType extends AbstractLongStringType {
+
+ public int sqlType() {
+ return Types.CLOB;
+ }
+
+ public String getName() { return "materialized_clob"; }
+}
\ No newline at end of file
Modified: core/trunk/core/src/main/java/org/hibernate/type/TextType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/TextType.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/core/src/main/java/org/hibernate/type/TextType.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -1,3 +1,4 @@
+//$Id: $
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
@@ -24,79 +25,21 @@
*/
package org.hibernate.type;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
import java.sql.Types;
-import org.hibernate.HibernateException;
-
/**
- * <tt>text</tt>: A type that maps an SQL CLOB to a Java String.
- * @author Gavin King, Bertrand Renuart
+ * <tt>text</tt>: A type that maps an SQL LONGVARCHAR to a Java String.
+ *
+ * @author Gail Badner
*/
-public class TextType extends ImmutableType {
+public class TextType extends AbstractLongStringType {
- public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
- String str = (String) value;
- st.setCharacterStream( index, new StringReader(str), str.length() );
- }
-
- public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-
- // Retrieve the value of the designated column in the current row of this
- // ResultSet object as a java.io.Reader object
- Reader charReader = rs.getCharacterStream(name);
-
- // if the corresponding SQL value is NULL, the reader we got is NULL as well
- if (charReader==null) return null;
-
- // Fetch Reader content up to the end - and put characters in a StringBuffer
- StringBuffer sb = new StringBuffer();
- try {
- char[] buffer = new char[2048];
- while (true) {
- int amountRead = charReader.read(buffer, 0, buffer.length);
- if ( amountRead == -1 ) break;
- sb.append(buffer, 0, amountRead);
- }
- }
- catch (IOException ioe) {
- throw new HibernateException( "IOException occurred reading text", ioe );
- }
- finally {
- try {
- charReader.close();
- }
- catch (IOException e) {
- throw new HibernateException( "IOException occurred closing stream", e );
- }
- }
-
- // Return StringBuffer content as a large String
- return sb.toString();
- }
-
public int sqlType() {
- return Types.CLOB; //or Types.LONGVARCHAR?
+ return Types.LONGVARCHAR;
}
- public Class getReturnedClass() {
- return String.class;
- }
-
public String getName() { return "text"; }
- public String toString(Object val) {
- return (String) val;
- }
- public Object fromStringValue(String xml) {
- return xml;
- }
-
}
Modified: core/trunk/core/src/main/java/org/hibernate/type/TypeFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/TypeFactory.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/core/src/main/java/org/hibernate/type/TypeFactory.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -90,7 +90,10 @@
basics.put( Hibernate.TRUE_FALSE.getName(), Hibernate.TRUE_FALSE );
basics.put( Hibernate.YES_NO.getName(), Hibernate.YES_NO );
basics.put( Hibernate.BINARY.getName(), Hibernate.BINARY );
+ basics.put( Hibernate.IMAGE.getName(), Hibernate.IMAGE );
basics.put( Hibernate.TEXT.getName(), Hibernate.TEXT );
+ basics.put( Hibernate.MATERIALIZED_BLOB.getName(), Hibernate.MATERIALIZED_BLOB );
+ basics.put( Hibernate.MATERIALIZED_CLOB.getName(), Hibernate.MATERIALIZED_CLOB );
basics.put( Hibernate.BLOB.getName(), Hibernate.BLOB );
basics.put( Hibernate.CLOB.getName(), Hibernate.CLOB );
basics.put( Hibernate.BIG_DECIMAL.getName(), Hibernate.BIG_DECIMAL );
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/BlobLocatorTest.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,196 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.lob;
+
+import java.sql.Blob;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.Session;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Tests lazy materialization of data mapped by
+ * {@link org.hibernate.type.BlobType}, as well as bounded and unbounded
+ * materialization and mutation.
+ *
+ * @author Steve Ebersole
+ */
+public class BlobLocatorTest extends DatabaseSpecificFunctionalTestCase {
+ private static final int BLOB_SIZE = 10000;
+
+ public BlobLocatorTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/LobMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( BlobLocatorTest.class );
+ }
+
+ public boolean appliesTo(Dialect dialect) {
+ if ( ! dialect.supportsExpectedLobUsagePattern() ) {
+ reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
+ return false;
+ }
+ return true;
+ }
+
+ public void testBoundedBlobLocatorAccess() throws Throwable {
+ byte[] original = buildRecursively( BLOB_SIZE, true );
+ byte[] changed = buildRecursively( BLOB_SIZE, false );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LobHolder entity = new LobHolder();
+ entity.setBlobLocator( Hibernate.createBlob( original ) );
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
+ assertEquals( original, extractData( entity.getBlobLocator() ) );
+ s.getTransaction().commit();
+ s.close();
+
+ // test mutation via setting the new clob data...
+ if ( supportsLobValueChangePropogation() ) {
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ entity.getBlobLocator().truncate( 1 );
+ entity.getBlobLocator().setBytes( 1, changed );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ assertNotNull( entity.getBlobLocator() );
+ assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
+ assertEquals( changed, extractData( entity.getBlobLocator() ) );
+ entity.getBlobLocator().truncate( 1 );
+ entity.getBlobLocator().setBytes( 1, original );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ // test mutation via supplying a new clob locator instance...
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ assertNotNull( entity.getBlobLocator() );
+ assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
+ assertEquals( original, extractData( entity.getBlobLocator() ) );
+ entity.setBlobLocator( Hibernate.createBlob( changed ) );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
+ assertEquals( changed, extractData( entity.getBlobLocator() ) );
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ }
+
+ public void testUnboundedBlobLocatorAccess() throws Throwable {
+ if ( ! supportsUnboundedLobLocatorMaterialization() ) {
+ return;
+ }
+
+ // Note: unbounded mutation of the underlying lob data is completely
+ // unsupported; most databases would not allow such a construct anyway.
+ // Thus here we are only testing materialization...
+
+ byte[] original = buildRecursively( BLOB_SIZE, true );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LobHolder entity = new LobHolder();
+ entity.setBlobLocator( Hibernate.createBlob( original ) );
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ // load the entity with the clob locator, and close the session/transaction;
+ // at that point it is unbounded...
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ s.getTransaction().commit();
+ s.close();
+
+ assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
+ assertEquals( original, extractData( entity.getBlobLocator() ) );
+
+ s = openSession();
+ s.beginTransaction();
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ private byte[] extractData(Blob blob) throws Throwable {
+ return blob.getBytes( 1, ( int ) blob.length() );
+ }
+
+
+ private byte[] buildRecursively(int size, boolean on) {
+ byte[] data = new byte[size];
+ data[0] = mask( on );
+ for ( int i = 0; i < size; i++ ) {
+ data[i] = mask( on );
+ on = !on;
+ }
+ return data;
+ }
+
+ private byte mask(boolean on) {
+ return on ? ( byte ) 1 : ( byte ) 0;
+ }
+
+ public static void assertEquals(byte[] val1, byte[] val2) {
+ if ( !ArrayHelper.isEquals( val1, val2 ) ) {
+ throw new AssertionFailedError( "byte arrays did not match" );
+ }
+ }
+}
Deleted: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/BlobTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/BlobTest.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/BlobTest.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -1,200 +0,0 @@
-package org.hibernate.test.lob;
-
-import java.sql.Blob;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.Test;
-
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.Session;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
-import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * {@inheritDoc}
- *
- * @author Steve Ebersole
- */
-public class BlobTest extends DatabaseSpecificFunctionalTestCase {
- private static final int BLOB_SIZE = 10000;
-
- public BlobTest(String name) {
- super( name );
- }
-
- public String[] getMappings() {
- return new String[] { "lob/LobMappings.hbm.xml" };
- }
-
- public static Test suite() {
- return new FunctionalTestClassTestSuite( BlobTest.class );
- }
-
- public boolean appliesTo(Dialect dialect) {
- if ( ! dialect.supportsExpectedLobUsagePattern() ) {
- reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
- return false;
- }
- return true;
- }
-
- public void testBoundedMaterializedBlobAccess() {
- byte[] original = buildRecursively( BLOB_SIZE, true );
- byte[] changed = buildRecursively( BLOB_SIZE, false );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setMaterializedBlob( original );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( BLOB_SIZE, entity.getMaterializedBlob().length );
- assertEquals( original, entity.getMaterializedBlob() );
- entity.setMaterializedBlob( changed );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( BLOB_SIZE, entity.getMaterializedBlob().length );
- assertEquals( changed, entity.getMaterializedBlob() );
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
- }
-
- public void testBoundedBlobLocatorAccess() throws Throwable {
- byte[] original = buildRecursively( BLOB_SIZE, true );
- byte[] changed = buildRecursively( BLOB_SIZE, false );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setBlobLocator( Hibernate.createBlob( original ) );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
- assertEquals( original, extractData( entity.getBlobLocator() ) );
- s.getTransaction().commit();
- s.close();
-
- // test mutation via setting the new clob data...
- if ( supportsLobValueChangePropogation() ) {
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- entity.getBlobLocator().truncate( 1 );
- entity.getBlobLocator().setBytes( 1, changed );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- assertNotNull( entity.getBlobLocator() );
- assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
- assertEquals( changed, extractData( entity.getBlobLocator() ) );
- entity.getBlobLocator().truncate( 1 );
- entity.getBlobLocator().setBytes( 1, original );
- s.getTransaction().commit();
- s.close();
- }
-
- // test mutation via supplying a new clob locator instance...
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- assertNotNull( entity.getBlobLocator() );
- assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
- assertEquals( original, extractData( entity.getBlobLocator() ) );
- entity.setBlobLocator( Hibernate.createBlob( changed ) );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
- assertEquals( changed, extractData( entity.getBlobLocator() ) );
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
-
- }
-
- public void testUnboundedBlobLocatorAccess() throws Throwable {
- if ( ! supportsUnboundedLobLocatorMaterialization() ) {
- return;
- }
-
- // Note: unbounded mutation of the underlying lob data is completely
- // unsupported; most databases would not allow such a construct anyway.
- // Thus here we are only testing materialization...
-
- byte[] original = buildRecursively( BLOB_SIZE, true );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setBlobLocator( Hibernate.createBlob( original ) );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- // load the entity with the clob locator, and close the session/transaction;
- // at that point it is unbounded...
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- s.getTransaction().commit();
- s.close();
-
- assertEquals( BLOB_SIZE, entity.getBlobLocator().length() );
- assertEquals( original, extractData( entity.getBlobLocator() ) );
-
- s = openSession();
- s.beginTransaction();
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
- }
-
- private byte[] extractData(Blob blob) throws Throwable {
- return blob.getBytes( 1, ( int ) blob.length() );
- }
-
-
- private byte[] buildRecursively(int size, boolean on) {
- byte[] data = new byte[size];
- data[0] = mask( on );
- for ( int i = 0; i < size; i++ ) {
- data[i] = mask( on );
- on = !on;
- }
- return data;
- }
-
- private byte mask(boolean on) {
- return on ? ( byte ) 1 : ( byte ) 0;
- }
-
- public static void assertEquals(byte[] val1, byte[] val2) {
- if ( !ArrayHelper.isEquals( val1, val2 ) ) {
- throw new AssertionFailedError( "byte arrays did not match" );
- }
- }
-}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ClobLocatorTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ClobLocatorTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ClobLocatorTest.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,190 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.lob;
+
+import java.sql.Clob;
+
+import junit.framework.Test;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.Session;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.H2Dialect;
+import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * Tests lazy materialization of data mapped by
+ * {@link org.hibernate.type.ClobType} as well as bounded and unbounded
+ * materialization and mutation.
+ *
+ * @author Steve Ebersole
+ */
+public class ClobLocatorTest extends DatabaseSpecificFunctionalTestCase {
+ private static final int CLOB_SIZE = 10000;
+
+ public ClobLocatorTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/LobMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( ClobLocatorTest.class );
+ }
+
+ public boolean appliesTo(Dialect dialect) {
+ if ( ! dialect.supportsExpectedLobUsagePattern() ) {
+ reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
+ return false;
+ }
+ return true;
+ }
+
+ public void testBoundedClobLocatorAccess() throws Throwable {
+ String original = buildRecursively( CLOB_SIZE, 'x' );
+ String changed = buildRecursively( CLOB_SIZE, 'y' );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LobHolder entity = new LobHolder();
+ entity.setClobLocator( Hibernate.createClob( original ) );
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
+ assertEquals( original, extractData( entity.getClobLocator() ) );
+ s.getTransaction().commit();
+ s.close();
+
+ // test mutation via setting the new clob data...
+ if ( supportsLobValueChangePropogation() ) {
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ entity.getClobLocator().truncate( 1 );
+ entity.getClobLocator().setString( 1, changed );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ assertNotNull( entity.getClobLocator() );
+ assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
+ assertEquals( changed, extractData( entity.getClobLocator() ) );
+ entity.getClobLocator().truncate( 1 );
+ entity.getClobLocator().setString( 1, original );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ // test mutation via supplying a new clob locator instance...
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
+ assertNotNull( entity.getClobLocator() );
+ assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
+ assertEquals( original, extractData( entity.getClobLocator() ) );
+ entity.setClobLocator( Hibernate.createClob( changed ) );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
+ assertEquals( changed, extractData( entity.getClobLocator() ) );
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ }
+
+ public void testUnboundedClobLocatorAccess() throws Throwable {
+ if ( ! supportsUnboundedLobLocatorMaterialization() ) {
+ return;
+ }
+
+ // Note: unbounded mutation of the underlying lob data is completely
+ // unsupported; most databases would not allow such a construct anyway.
+ // Thus here we are only testing materialization...
+
+ String original = buildRecursively( CLOB_SIZE, 'x' );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LobHolder entity = new LobHolder();
+ entity.setClobLocator( Hibernate.createClob( original ) );
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ // load the entity with the clob locator, and close the session/transaction;
+ // at that point it is unbounded...
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
+ s.getTransaction().commit();
+ s.close();
+
+ assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
+ assertEquals( original, extractData( entity.getClobLocator() ) );
+
+ s = openSession();
+ s.beginTransaction();
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ private String extractData(Clob clob) throws Throwable {
+ if ( getDialect() instanceof H2Dialect ) {
+ return clob.getSubString( 1, ( int ) clob.length() );
+ }
+ else {
+ char[] data = new char[ (int) clob.length() ];
+ clob.getCharacterStream().read( data );
+ return new String( data );
+ }
+ }
+
+
+ private String buildRecursively(int size, char baseChar) {
+ StringBuffer buff = new StringBuffer();
+ for( int i = 0; i < size; i++ ) {
+ buff.append( baseChar );
+ }
+ return buff.toString();
+ }
+}
Deleted: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ClobTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ClobTest.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ClobTest.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -1,196 +0,0 @@
-package org.hibernate.test.lob;
-
-import java.sql.Clob;
-
-import junit.framework.Test;
-
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.Session;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.H2Dialect;
-import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
-import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
-
-/**
- * Test various access scenarios for eager and lazy materialization
- * of CLOB data, as well as bounded and unbounded materialization
- * and mutation.
- *
- * @author Steve Ebersole
- */
-public class ClobTest extends DatabaseSpecificFunctionalTestCase {
- private static final int CLOB_SIZE = 10000;
-
- public ClobTest(String name) {
- super( name );
- }
-
- public String[] getMappings() {
- return new String[] { "lob/LobMappings.hbm.xml" };
- }
-
- public static Test suite() {
- return new FunctionalTestClassTestSuite( ClobTest.class );
- }
-
- public boolean appliesTo(Dialect dialect) {
- if ( ! dialect.supportsExpectedLobUsagePattern() ) {
- reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
- return false;
- }
- return true;
- }
-
- public void testBoundedMaterializedClobAccess() {
- String original = buildRecursively( CLOB_SIZE, 'x' );
- String changed = buildRecursively( CLOB_SIZE, 'y' );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setMaterializedClob( original );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( CLOB_SIZE, entity.getMaterializedClob().length() );
- assertEquals( original, entity.getMaterializedClob() );
- entity.setMaterializedClob( changed );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( CLOB_SIZE, entity.getMaterializedClob().length() );
- assertEquals( changed, entity.getMaterializedClob() );
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
- }
-
- public void testBoundedClobLocatorAccess() throws Throwable {
- String original = buildRecursively( CLOB_SIZE, 'x' );
- String changed = buildRecursively( CLOB_SIZE, 'y' );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setClobLocator( Hibernate.createClob( original ) );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
- assertEquals( original, extractData( entity.getClobLocator() ) );
- s.getTransaction().commit();
- s.close();
-
- // test mutation via setting the new clob data...
- if ( supportsLobValueChangePropogation() ) {
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- entity.getClobLocator().truncate( 1 );
- entity.getClobLocator().setString( 1, changed );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- assertNotNull( entity.getClobLocator() );
- assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
- assertEquals( changed, extractData( entity.getClobLocator() ) );
- entity.getClobLocator().truncate( 1 );
- entity.getClobLocator().setString( 1, original );
- s.getTransaction().commit();
- s.close();
- }
-
- // test mutation via supplying a new clob locator instance...
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId(), LockMode.UPGRADE );
- assertNotNull( entity.getClobLocator() );
- assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
- assertEquals( original, extractData( entity.getClobLocator() ) );
- entity.setClobLocator( Hibernate.createClob( changed ) );
- s.getTransaction().commit();
- s.close();
-
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
- assertEquals( changed, extractData( entity.getClobLocator() ) );
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
-
- }
-
- public void testUnboundedClobLocatorAccess() throws Throwable {
- if ( ! supportsUnboundedLobLocatorMaterialization() ) {
- return;
- }
-
- // Note: unbounded mutation of the underlying lob data is completely
- // unsupported; most databases would not allow such a construct anyway.
- // Thus here we are only testing materialization...
-
- String original = buildRecursively( CLOB_SIZE, 'x' );
-
- Session s = openSession();
- s.beginTransaction();
- LobHolder entity = new LobHolder();
- entity.setClobLocator( Hibernate.createClob( original ) );
- s.save( entity );
- s.getTransaction().commit();
- s.close();
-
- // load the entity with the clob locator, and close the session/transaction;
- // at that point it is unbounded...
- s = openSession();
- s.beginTransaction();
- entity = ( LobHolder ) s.get( LobHolder.class, entity.getId() );
- s.getTransaction().commit();
- s.close();
-
- assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
- assertEquals( original, extractData( entity.getClobLocator() ) );
-
- s = openSession();
- s.beginTransaction();
- s.delete( entity );
- s.getTransaction().commit();
- s.close();
- }
-
- private String extractData(Clob clob) throws Throwable {
- if ( getDialect() instanceof H2Dialect ) {
- return clob.getSubString( 1, ( int ) clob.length() );
- }
- else {
- char[] data = new char[ (int) clob.length() ];
- clob.getCharacterStream().read( data );
- return new String( data );
- }
- }
-
-
- private String buildRecursively(int size, char baseChar) {
- StringBuffer buff = new StringBuffer();
- for( int i = 0; i < size; i++ ) {
- buff.append( baseChar );
- }
- return buff.toString();
- }
-}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ImageMappings.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ImageMappings.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ImageMappings.hbm.xml 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.lob">
+
+ <class name="LongByteArrayHolder" table="LOB_ENTITY_IMAGE">
+ <id name="id" type="long" column="ID">
+ <generator class="increment"/>
+ </id>
+
+ <property name="longByteArray" column="LONG_BYTE_ARRAY" type="image" length="15000"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ImageTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ImageTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/ImageTest.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,51 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.lob;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * Tests eager materialization and mutation of data mapped by
+ * {@link org.hibernate.type.ImageType}.
+ *
+ * @author Gail Badner
+ */
+public class ImageTest extends LongByteArrayTest {
+
+ public ImageTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/ImageMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( ImageTest.class );
+ }
+}
\ No newline at end of file
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LobHolder.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LobHolder.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LobHolder.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -7,21 +7,10 @@
/**
* An entity containing all kinds of good LOB-type data...
* <p/>
- * {@link #serialData} is used to hold general serializable data which is
- * mapped via the {@link org.hibernate.type.SerializableType}.
- * <p/>
- * {@link #materializedClob} is used to hold CLOB data that is materialized
- * into a String immediately; it is mapped via the
- * {@link org.hibernate.type.TextType}.
- * <p/>
* {@link #clobLocator} is used to hold CLOB data that is materialized lazily
* via a JDBC CLOB locator; it is mapped via the
* {@link org.hibernate.type.ClobType}
* <p/>
- * {@link #materializedBlob} is used to hold BLOB data that is materialized
- * into a byte array immediately; it is mapped via the
- * {@link org.hibernate.test.lob.MaterializedBlobType}.
- * <p/>
* {@link #blobLocator} is used to hold BLOB data that is materialized lazily
* via a JDBC BLOB locator; it is mapped via the
* {@link org.hibernate.type.BlobType}
@@ -32,12 +21,8 @@
public class LobHolder {
private Long id;
- private Serializable serialData;
-
- private String materializedClob;
private Clob clobLocator;
- private byte[] materializedBlob;
private Blob blobLocator;
public Long getId() {
@@ -48,22 +33,6 @@
this.id = id;
}
- public Serializable getSerialData() {
- return serialData;
- }
-
- public void setSerialData(Serializable serialData) {
- this.serialData = serialData;
- }
-
- public String getMaterializedClob() {
- return materializedClob;
- }
-
- public void setMaterializedClob(String materializedClob) {
- this.materializedClob = materializedClob;
- }
-
public Clob getClobLocator() {
return clobLocator;
}
@@ -72,14 +41,6 @@
this.clobLocator = clobLocator;
}
- public byte[] getMaterializedBlob() {
- return materializedBlob;
- }
-
- public void setMaterializedBlob(byte[] materializedBlob) {
- this.materializedBlob = materializedBlob;
- }
-
public Blob getBlobLocator() {
return blobLocator;
}
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LobMappings.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LobMappings.hbm.xml 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LobMappings.hbm.xml 2009-05-01 23:21:00 UTC (rev 16501)
@@ -10,13 +10,9 @@
<generator class="increment"/>
</id>
- <property name="serialData" column="SER_DATA" type="serializable"/>
+ <property name="clobLocator" column="CLOB_DATA" type="clob" length="15000" />
- <property name="materializedClob" column="MAT_CLOB_DATA" type="text" length="15000"/>
- <property name="clobLocator" column="CLOB_DATA" type="clob" length="15000"/>
-
- <property name="materializedBlob" column="MAT_BLOB_DATA" type="org.hibernate.test.lob.MaterializedBlobType" length="15000"/>
- <property name="blobLocator" column="BLOB_DATA" type="blob" length="15000"/>
+ <property name="blobLocator" column="BLOB_DATA" type="blob" length="15000" />
</class>
</hibernate-mapping>
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayHolder.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayHolder.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayHolder.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,54 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.lob;
+
+/**
+ * An entity containing data that is materialized into a byte array immediately.
+ * The hibernate type mapped for {@link #longByteArray} determines the SQL type
+ * asctually used.
+ *
+ * @author Gail Badner
+ */
+public class LongByteArrayHolder {
+ private Long id;
+ private byte[] longByteArray;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public byte[] getLongByteArray() {
+ return longByteArray;
+ }
+
+ public void setLongByteArray(byte[] longByteArray) {
+ this.longByteArray = longByteArray;
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongByteArrayTest.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,110 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.lob;
+
+import junit.framework.AssertionFailedError;
+import org.hibernate.Session;
+import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Tests eager materialization and mutation of long byte arrays.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class LongByteArrayTest extends DatabaseSpecificFunctionalTestCase {
+ private static final int ARRAY_SIZE = 10000;
+
+ public LongByteArrayTest(String name) {
+ super( name );
+ }
+
+ public void testBoundedLongByteArrayAccess() {
+ byte[] original = buildRecursively( ARRAY_SIZE, true );
+ byte[] changed = buildRecursively( ARRAY_SIZE, false );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LongByteArrayHolder entity = new LongByteArrayHolder();
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongByteArrayHolder ) s.get( LongByteArrayHolder.class, entity.getId() );
+ assertNull( entity.getLongByteArray() );
+ entity.setLongByteArray( original );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongByteArrayHolder ) s.get( LongByteArrayHolder.class, entity.getId() );
+ assertEquals( ARRAY_SIZE, entity.getLongByteArray().length );
+ assertEquals( original, entity.getLongByteArray() );
+ entity.setLongByteArray( changed );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongByteArrayHolder ) s.get( LongByteArrayHolder.class, entity.getId() );
+ assertEquals( ARRAY_SIZE, entity.getLongByteArray().length );
+ assertEquals( changed, entity.getLongByteArray() );
+ entity.setLongByteArray( null );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongByteArrayHolder ) s.get( LongByteArrayHolder.class, entity.getId() );
+ assertNull( entity.getLongByteArray() );
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ private byte[] buildRecursively(int size, boolean on) {
+ byte[] data = new byte[size];
+ data[0] = mask( on );
+ for ( int i = 0; i < size; i++ ) {
+ data[i] = mask( on );
+ on = !on;
+ }
+ return data;
+ }
+
+ private byte mask(boolean on) {
+ return on ? ( byte ) 1 : ( byte ) 0;
+ }
+
+ public static void assertEquals(byte[] val1, byte[] val2) {
+ if ( !ArrayHelper.isEquals( val1, val2 ) ) {
+ throw new AssertionFailedError( "byte arrays did not match" );
+ }
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongStringHolder.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongStringHolder.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongStringHolder.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,53 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.lob;
+
+/**
+ * An entity containing data that is materialized into a String immediately.
+ *
+ * @author Gail Badner
+ */
+public class LongStringHolder {
+ private Long id;
+
+ private String longString;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getLongString() {
+ return longString;
+ }
+
+ public void setLongString(String longString) {
+ this.longString = longString;
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongStringTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongStringTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/LongStringTest.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,99 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.lob;
+
+import junit.framework.Test;
+
+import org.hibernate.Session;
+import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * Tests eager materialization and mutation of long strings.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class LongStringTest extends DatabaseSpecificFunctionalTestCase {
+ private static final int LONG_STRING_SIZE = 10000;
+
+ public LongStringTest(String name) {
+ super( name );
+ }
+
+ public void testBoundedLongStringAccess() {
+ String original = buildRecursively( LONG_STRING_SIZE, 'x' );
+ String changed = buildRecursively( LONG_STRING_SIZE, 'y' );
+
+ Session s = openSession();
+ s.beginTransaction();
+ LongStringHolder entity = new LongStringHolder();
+ s.save( entity );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
+ assertNull( entity.getLongString() );
+ entity.setLongString( original );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
+ assertEquals( LONG_STRING_SIZE, entity.getLongString().length() );
+ assertEquals( original, entity.getLongString() );
+ entity.setLongString( changed );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
+ assertEquals( LONG_STRING_SIZE, entity.getLongString().length() );
+ assertEquals( changed, entity.getLongString() );
+ entity.setLongString( null );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
+ assertNull( entity.getLongString() );
+ s.delete( entity );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ private String buildRecursively(int size, char baseChar) {
+ StringBuffer buff = new StringBuffer();
+ for( int i = 0; i < size; i++ ) {
+ buff.append( baseChar );
+ }
+ return buff.toString();
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobMappings.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobMappings.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobMappings.hbm.xml 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.lob">
+
+ <class name="LongByteArrayHolder" table="LOB_ENTITY_MAT_BLOB">
+ <id name="id" type="long" column="ID">
+ <generator class="increment"/>
+ </id>
+
+ <property name="longByteArray" column="LONG_BYTE_ARRAY" type="materialized_blob" length="15000"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobTest.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,60 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.lob;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Tests eager materialization and mutation of data mapped by
+ * {@link org.hibernate.type.MaterializedBlobType}.
+ *
+ * @author Gail Badner
+ */
+public class MaterializedBlobTest extends LongByteArrayTest {
+
+ public MaterializedBlobTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/MaterializedBlobMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( MaterializedBlobTest.class );
+ }
+
+ public boolean appliesTo(Dialect dialect) {
+ if ( ! dialect.supportsExpectedLobUsagePattern() ) {
+ reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
Deleted: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobType.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobType.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedBlobType.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -1,33 +0,0 @@
-package org.hibernate.test.lob;
-
-import java.sql.Types;
-
-import org.hibernate.type.AbstractBynaryType;
-
-/**
- * {@inheritDoc}
- *
- * @author Steve Ebersole
- */
-public class MaterializedBlobType extends AbstractBynaryType {
-
- public int sqlType() {
- return Types.BLOB;
- }
-
- public String getName() {
- return "materialized-blob";
- }
-
- public Class getReturnedClass() {
- return byte[].class;
- }
-
- protected Object toExternalFormat(byte[] bytes) {
- return bytes;
- }
-
- protected byte[] toInternalFormat(Object bytes) {
- return ( byte[] ) bytes;
- }
-}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobMappings.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobMappings.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobMappings.hbm.xml 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.lob">
+
+ <class name="LongStringHolder" table="LOB_ENTITY_MAT_CLOB">
+ <id name="id" type="long" column="ID">
+ <generator class="increment"/>
+ </id>
+
+ <property name="longString" column="LONG_STR" type="materialized_clob" length="15000"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/MaterializedClobTest.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,60 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.lob;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Tests eager materialization and mutation of data mapped by
+ * {@link org.hibernate.type.MaterializedClobType}.
+ *
+ * @author Gail Badner
+ */
+public class MaterializedClobTest extends LongStringTest {
+
+ public MaterializedClobTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/MaterializedClobMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( MaterializedClobTest.class );
+ }
+
+ public boolean appliesTo(Dialect dialect) {
+ if ( ! dialect.supportsExpectedLobUsagePattern() ) {
+ reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableHolder.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableHolder.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableHolder.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,56 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.lob;
+
+import java.io.Serializable;
+
+/**
+ * An entity containing serializable data which is
+ * mapped via the {@link org.hibernate.type.SerializableType}.
+ *
+ * @author Steve Ebersole
+ */
+public class SerializableHolder {
+ private Long id;
+
+ private Serializable serialData;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Serializable getSerialData() {
+ return serialData;
+ }
+
+ public void setSerialData(Serializable serialData) {
+ this.serialData = serialData;
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableMappings.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableMappings.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableMappings.hbm.xml 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.lob">
+
+ <class name="SerializableHolder" table="LOB_ENTITY">
+ <id name="id" type="long" column="ID">
+ <generator class="increment"/>
+ </id>
+
+ <property name="serialData" column="SER_DATA" type="serializable"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableTypeTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableTypeTest.java 2009-05-01 20:26:15 UTC (rev 16500)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/SerializableTypeTest.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -24,7 +24,7 @@
}
public String[] getMappings() {
- return new String[] { "lob/LobMappings.hbm.xml" };
+ return new String[] { "lob/SerializableMappings.hbm.xml" };
}
public static Test suite() {
@@ -37,30 +37,49 @@
}
public void testNewSerializableType() {
- // Sybase dialects do not support ResultSet.getBlob(String)
- if ( getDialect() instanceof SybaseDialect || getDialect() instanceof Sybase11Dialect || getDialect() instanceof SybaseASE15Dialect || getDialect() instanceof SybaseAnywhereDialect ) {
- return;
- }
+ final String initialPayloadText = "Initial payload";
+ final String changedPayloadText = "Changed payload";
- final String payloadText = "Initial payload";
-
Session s = openSession();
s.beginTransaction();
- LobHolder holder = new LobHolder();
- holder.setSerialData( new SerializableData( payloadText ) );
+ SerializableHolder holder = new SerializableHolder();
s.save( holder );
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
- holder = ( LobHolder ) s.get( LobHolder.class, holder.getId() );
+ holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
+ assertNull( holder.getSerialData() );
+ holder.setSerialData( new SerializableData( initialPayloadText ) );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
SerializableData serialData = ( SerializableData ) holder.getSerialData();
- assertEquals( payloadText, serialData.getPayload() );
+ assertEquals( initialPayloadText, serialData.getPayload() );
+ holder.setSerialData( new SerializableData( changedPayloadText ) );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
+ serialData = ( SerializableData ) holder.getSerialData();
+ assertEquals( changedPayloadText, serialData.getPayload() );
+ holder.setSerialData( null );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
+ assertNull( holder.getSerialData() );
s.delete( holder );
s.getTransaction().commit();
s.close();
}
-
}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/TextMappings.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/TextMappings.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/TextMappings.hbm.xml 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.lob">
+
+ <class name="LongStringHolder" table="LOB_ENTITY_TEXT">
+ <id name="id" type="long" column="ID">
+ <generator class="increment"/>
+ </id>
+
+ <property name="longString" column="LONG_STR" type="text" length="15000"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/lob/TextTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/lob/TextTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/lob/TextTest.java 2009-05-01 23:21:00 UTC (rev 16501)
@@ -0,0 +1,51 @@
+//$Id: $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.lob;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * Test eager materialization and mutation data mapped by
+ * #{@link org.hibernate.type.TextType}.
+ *
+ * @author Gail Badner
+ */
+public class TextTest extends LongStringTest {
+
+ public TextTest(String name) {
+ super( name );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "lob/TextMappings.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( TextTest.class );
+ }
+}
\ No newline at end of file
15 years, 7 months