简体   繁体   中英

JPA: Partial contraint

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 @UniqueConstraint 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM