Set transient value from database with Spring Data

2019-07-03 16:39发布

I wonder if there is a way to retrieve a generated value from database as an extra column and map it to a transient value.

I'll try to explain myself, I wish something like this:

@Entity
@Table(name = "thing")
public class Thing {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "itemid")
    private Long itemId;

    private String someValue;

    @Transient
    private double distance;

    // constructors, getters, setters, etc.. (include transient methods)
}

Repository("thingRepository")
public interface ThingRepository extends PagingAndSortingRepository<Thing, Long> {

    @Query("SELECT t, cos(someDouble)*sin(:someDouble) AS distance FROM Thing t WHERE someValue = :someValue AND someDouble = :someDouble AND distance > 30")
    Page<Thing> findByParams(@Param("someValue") String someValue, @Param("someDouble") double someDouble, Pageable pageable);
}

I'm using @Query annotation for simplicity, so I'm limited because of that. HAVING clause it's not allowed, and the current example it's not working.

As I need the value stored in database, and the value passed from service, I'm in need to do the filtering from database.

Or maybe it's there another approach to doing this?

Thank you in advance.

1条回答
爷、活的狠高调
2楼-- · 2019-07-03 17:20

I think you could do something like this. Create a new instance using a different constructor by using JPQL New feature.

@Query("SELECT new Thing(t, cos(t.someDouble)*sin(t.someDouble))FROM Thing t WHERE t.someValue = :someValue AND t.someDouble = :someDouble AND cos(t.someDouble)*sin(t.someDouble)> 30")

Just add the constructor as below.

public class Thing {
  // the code you already had

  public Thing(Thing t, double distance){
     this.itemId = t.itemId;
     this.someValue = t.someValue;
     this.distance = distance;
   }
}
查看更多
登录 后发表回答