[
http://opensource.atlassian.com/projects/hibernate/browse/ANN-472?page=co...
]
Ted Bergeron commented on ANN-472:
----------------------------------
API Extension:
getInvalidValues could accept the bean and use Java 5's varargs ability to allow for
one or more String propertyNames: public InvalidValue[] getInvalidValues(T bean,
String... propertyNames)
getPotentialInvalidValues would have to accept a Map: public InvalidValue[]
getPotentialInvalidValues(Map<String, Object> propertyValueMap)
Now you've got me thinking about the details of doing this exactly right. The
validations need to honor priorities. IE, if instead of name, I am putting unique
constraints on an email property, I'd best make sure the user input passes basic
validation first. No sense in hitting the database looking to see if invalid data would
violate a unique constraint.
My ideal solution is not possible currently, thanks to Java 5's limitations around
inheritance and annotation overriding. I'll list the code below in the hopes it gives
you an idea, or that java 6/7 makes this possible:
in NameableObject
...
@Column(name = "name")
@Length(min = 1, max = NAME_LENGTH)
@NotNull
public String getName() {
return name;
}
in LookupObject extends NameableObject
...
@Override
@Column(name = "name", unique = true) // We add a unique constraint for
lookupObjects
@Length(min = 1, max = NAME_LENGTH)
@NotNull
public String getName() {
return super.getName();
}
in CustomerBoundLookupObject extends LookupObject
...
@Override
@Unique(composite = true, constraintname = "cust_name")
@Column(name = "name")
@Length(min = 1, max = NAME_LENGTH)
@NotNull
public String getName() {
return super.getName();
}
@Unique(composite = true, constraintname = "cust_name")
@NotNull
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
@JoinColumn(name = "cust_id")
public Customer getCustomer() {
return customer;
}
The idea here is that I can query a property via reflection and ask if it needs to be
unique, or participates in one or more composite unique constraints. If I find one or
more composite constraints, I can iterate over the bean's properties looking for the
other properties that belong to the constraint. On finding the 2+ properties, I could
generate a select statement with the 2+ columns in the where clause to test if a transient
bean would violate my constraint. If the validator would automatically generate the
selects when validating, but only if the simple validations all pass, that would be
perfect.
At the bean level, we could optionally define the constraint much like:
@SequenceGenerator We'd give it the meaningless name to match with the @Unique
annotation, and the real database name of the constraint.
Without the inheritance that is impossible, this would still be useful as is. If you do
not agree with any of the above, then at the very least, changing:
uniqueConstraints = {@UniqueConstraint(columnNames={"month", "day"})}
to use property names vs column names would help with the reflection. (And hibernate can
easily derive column names from properties.)
@UniqueConstraint declaration is not friendly towards inheritance or
reflection
-------------------------------------------------------------------------------
Key: ANN-472
URL:
http://opensource.atlassian.com/projects/hibernate/browse/ANN-472
Project: Hibernate Annotations
Type: Improvement
Versions: 3.2.0.ga
Environment: Hibernate 3.2 GA
Reporter: Ted Bergeron
The current way to define a composite unique constraint is limiting.
@Table(name="tbl_sky",
uniqueConstraints = {@UniqueConstraint(columnNames={"month",
"day"})}
)
Suppose I have an abstract base class called A that gives me Id and Name, subclassed by
abstract class B that gives me Customer. Then I have many concrete classes that subclass
B. For all of these, I'd want the combination of Name and Customer to be unique. As
I do not use @Table with abstract base classes, I currently have to repeat:
uniqueConstraints = {@UniqueConstraint(columnNames={"name",
"customer_id"})} on all concrete classes.
If we had an alternate way to define these constraints at the property level (as XDoclet
did with hibernate 2), I could define this in the base classes and inherit the constraint
declaration.
The other need is that I would like to use reflection to scan the properties and apply
proper validations in the view layer. With @Column(unique = true) this is easy to do.
The view layer makes an AJAX call and all is well. For a composite constraint, it does
not work well currently.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira