I need something like a partial contraint for one of my entities.
@Entity
public class MyEntity
{
@NotNull
private String name;
@ManyToOne @NotNull
private Type type;
}
Only for a sinlge type
I need the name
to be unique.
Is this possible with a @UniqueCon开发者_如何学Cstraint
or do I need to implement this with a @PrePersist
and @PreUpdate
listener? So far I haven't implemented such a listener, but even if I check the contraint in this listener, does it guarantee to prevent a duplicate entry?
Update
Let's assume the constraint should only be active for type=special
- Allowed
{id=1,type=normal,name=Test},{id=2,type=normal,name=Test}
- Not allowed:
{id=3,type=special,name=Test},{id=4,type=special,name=Test}
My understanding of the @UniqueContraint is that it may contain a list of column names that together define the uniqueness.
See: unique constraint check in JPA
@UniqueConstraint(columnNames={"name", "type"})
I would expect this to enforce uniqueness across name and type. (No time to test though.)
Edit:
Aha. So now I understand the problem. How about this for an approach introduce a third attribute:
int mySpecialValue;
This attribute has no public setter. Instead its value is set by the setType() with logic like this:
public void setType(String theType){
type = theType;
if ( "special".equals(type) ){
mySpecialValue = 0;
} else {
mySpecialValue = makeUniqueInt(); // eg. some date twiddling
}
}
Now set the unique constraint to include the mySpecialValue. Hence for all specials the uniqueness depends entirely on the name, for others there is always a differentiator so the names can duplicate.
Allowed {id=1,type=normal,name=Test, msv = 343223 },
{id=2,type=normal,name=Test, msv = 777654 } <== not dup
Not allowed: {id=3,type=special,name=Test, msv =0 },
{id=4,type=special,name=Test, msv =0} <== dup
See conditional unique constraint for a similar question. I don't think a listener is the right place to define somthing like that. I would either implement it in the database, using a check constraint or a unique constraint on a view, or as a functional check in your application.
精彩评论