简体   繁体   中英

How to Map a CASE Statement alias to a java pojo attribute in JPA/JPQL?

JPQL:

@Query(value="SELECT emp,CASE WHEN emp.country='india' THEN 'INDIAN' ELSE 'OTHER' END AS originCountry FROM EMPLOYEE emp")   //originCountry is not a column of Entity/Table
List<Employee> findAllEmployee()

Now how to map originCountry to a java property/attribute? ALL result set attribute will be mapped to the employee object automatically but how to map the originCountry attribute as it is not coming from database table?

Java class:

@Table(name="employee")
@Entity
@Getter
@Setter
class Employee{

      @Id
      @Column(name="emp_id")
      private String empId;

      @Column(name="emp_name")
      private String empName;

      @Column(name="emp_address")
      private String empAddress;

      @Transient
      private String originCountry; //I want to map CASE statement alias result to this variable
      
}

Actually @Airy's assumption is absolutely relevant! I just have modeled the issue with a small h2 -based project. Disclaimer: it's just a piece of code of a synthetic model

Given : Pet entity. It has a typeCode property of Integer .

Todo : Implement another property, that'll return pet's type name by its typeCode .

@Entity
public class Pet {

  @Id
  @Column(name = "id", nullable = false)
  @GeneratedValue
  private Long id;

  @Column
  private String name;

  @Column
  private Integer typeCode;

  @Formula("case type_code when 1 then 'Cat' when 2 then 'Dog' else 'Chupacabra' end")
  private String typeName;
  
  //get, set etc

  @Override
  public String toString() {
    return new StringJoiner(", ", Pet.class.getSimpleName() + "[", "]")
        .add("id=" + getId())
        .add("name='" + getName() + "'")
        .add("typeCode=" + getTypeCode())
        .add("typeName='" + getTypeName() + "'")
        .toString();
  }
}

In a bootstrap:

var cat = new Pet();
cat.setName("Oscar");
cat.setTypeCode(1);

var dog = new Pet();
dog.setName("Lucky");
dog.setTypeCode(2);

var customPet = new Pet();
customPet.setName("Smoking kills");

petRepository.saveAll(List.of(cat, dog, customPet));

And test:

public void interact() {
    var pet1 = petRepository.findById(1L).get();
    var pet2 = petRepository.findById(2L).get();
    var pet = petRepository.findById(3L).get();

    System.out.println(pet1);
    System.out.println(pet2);
    System.out.println(pet);
}

Console:
Pet[id=1, name='Oscar', age=6, typeCode=1, typeName='Cat', type=CAT]
Pet[id=2, name='Lucky', age=10, typeCode=2, typeName='Dog', type=DOG]
Pet[id=3, name='Smoking kills', age=null, typeCode=null, typeName='Chupacabra', type=null]

From Hibernate 's reference of formula :

You can use a SQL fragment (aka formula) instead of mapping a property into a column

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