我有一个实体Person,其属性为Name。名称未标记为实体。对于Name类,我有一个AttributeConverter,它通过姓和名的字符串连接来创建全名。因此,对于个人实体,列名称的类型为字符串。
@Entity
public class Person {
// ...
@Convert(converter = NameAttributeConverter.class)
@Column
private Name name;
// ...
}
public final class Name implements Comparable, Serializable {
// ...
private String firstName;
private String lastName;
// ...
}
这有效。但是现在我想扩展我的人员存储库。我想按她的姓氏查找人。但是
List<Person> findByName_LastName(String lastName);
或
List<Person> findByNameLastName(String lastName);
不起作用。我收到以下异常:
PersonRepository.findByName_LastName(java.lang.String)! Illegal attempt to dereference path source [null.name] of basic type
我该如何解决问题?谢谢和问候
编辑:
public interface PersonRepository extends CrudRepository<Person, Long>{
// The repository works without the findByName...
// List<Person> findByName_LastName(String lastName);
}
这不适用于查询派生,也无法使用,因为一般而言,在您的情况下,转换所应用的功能是不可逆的。这意味着为了使Spring Data实现此功能,需要分析转换,将其求逆,即创建一组函数,这些函数从存储在数据库中的级联字符串生成名字和姓氏,并使用Criteria进行实现API。我认为这显然是无法完成的。
如果您知道应该执行什么查询,请使用@Query
注释。
更好的解决方案是将姓氏存储在单独的列中,以便可以轻松访问。
如果
由于将属性转换器用于name
列,因此将名字和姓氏视为数据库中的列。因此,JPA将name
视为类型为Name
的列,并且无法在Name
对象类型字段上进行查询。更好的解决方案是将名字和姓氏存储在单独的列中,以便您轻松查询。但是,如果您想创建一个姓和名的字段连续字段并查询连续字段,则可以使用@Formula()
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Formula(value = "CONCAT(last_name, first_name)")
private String name;