Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for SpEL as a scripting language usable with Hibernate Validator 4.1 @ScriptAssert [SPR-7651] #12307

Open
spring-projects-issues opened this issue Oct 13, 2010 · 3 comments
Labels
in: core type: enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Oct 13, 2010

Keith Donald opened SPR-7651 and commented

Have you seen the new @ScriptAssert constraint annotation in Hibernate Validator 4.1.0:

* A class-level constraint, that evaluates a script expression against the
* annotated element. This constraint can be used to implement validation
* routines, that depend on multiple attributes of the annotated element.

It'd be great if SpEL could be plugged in as the script expression language:

* For evaluation of expressions the Java Scripting API as defined by <a
* href="http://jcp.org/en/jsr/detail?id=223">JSR 223</a>
* ("Scripting for the Java<sup>TM</sup> Platform") is used. Therefore an
* implementation of that API must part of the class path. This is automatically
* the case when running on Java 6. For older Java versions, the JSR 223 RI can
* be added manually to the class path.

I noticed this when I needed a @FieldMatch type capability for doing field confirmation constraints. There is no such thing in JSR 303, Hibernate Validator, or Apachje Bean Validator, so I rolled my own class-level constraint from an example I found but then discovered this annotation after upgrading to Hibernate Validator 4.1.0.

References:
http://stackoverflow.com/questions/1972933/cross-field-validation-with-hibernate-validator-jsr-303


Affects: 3.0.3

Referenced from: commits 9008e08

6 votes, 5 watchers

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 17, 2017

James Howe commented

Giving this a little kick as it seems to be stuck Waiting for Triage but with no Assignee.

@spring-projects-issues spring-projects-issues added type: enhancement in: core labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 5.x Backlog milestone Jan 11, 2019
@OrangeDog
Copy link

@OrangeDog OrangeDog commented Mar 27, 2020

Again in a situation where this feature would've made everything easier.

@jhoeller jhoeller removed this from the 5.x Backlog milestone Aug 24, 2020
@jhoeller jhoeller added this to the General Backlog milestone Aug 24, 2020
@rubensa
Copy link

@rubensa rubensa commented Aug 5, 2021

I've just tried https://github.com/eobermuhlner/spel-scriptengine

You just need too add this to your pom.xml

    <dependency>
      <groupId>ch.obermuhlner</groupId>
      <artifactId>spel-scriptengine</artifactId>
      <version>1.0.0</version>
    </dependency>

And then use it with Hibernate Validator like this:

package org.eu.rubensa.model;

import java.time.Instant;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.ScriptAssert;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "sample")
@Data
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
@ScriptAssert.List({
    // Month valiadation
    @ScriptAssert(lang = "spel", alias = "_this", script = "#_this.getLower() == null || #_this.getHigher() == null || #_this.getHigher().compareTo(#_this.getLower()) >= 0", reportOn = "finalMonth", message = "{org.eu.rubensa.validation.LowerGreaterThanHigher.message}"),
    // Instant validation
    @ScriptAssert(lang = "spel", alias = "_this", script = "#_this.getStart() == null || #_this.getEnd() == null || #_this.getEnd().compareTo(#_this.getStart()) >= 0", reportOn = "fechaFinPresentacion", message = "{org.eu.rubensa.validation.StartGreaterThanEnd.message}") })
public class SampleEntity {
  @Id
  @Column(name = "id", nullable = false)
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sample_seq")
  @SequenceGenerator(name = "sample_seq", sequenceName = "sample_seq", allocationSize = 1)
  private Long id;

  @Column(name = "lower", nullable = false)
  @NotNull
  @Min(1)
  private Integer lower;

  @Column(name = "higher", nullable = false)
  @NotNull
  @Min(1)
  private Integer higher;

  @Column(name = "start", nullable = true)
  private Instant start;

  @Column(name = "end", nullable = true)
  private Instant end;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core type: enhancement
Projects
None yet
Development

No branches or pull requests

4 participants