英文:
Spring data JPA: find by column of custom class type's member
问题
I have an entity Person which has a property Name. Name is not marked as entity. For the Name class, I have an AttributeConverter which creates a full name by string concatenation of the first and last name. So, for the person entity, the column name is of type String.
@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;
// ...
}
This works. But now I want to extend my person repository. I want to find persons by their lastName. But
List<Person> findByName_LastName(String lastName);
or
List<Person> findByNameLastName(String lastName);
does not work. I get the following exception:
PersonRepository.findByName_LastName(java.lang.String)! Illegal attempt to dereference path source [null.name] of basic type
How can I solve the problem? Thanks and regards
EDIT:
public interface PersonRepository extends CrudRepository<Person, Long>{
// The repository works without the findByName...
// List<Person> findByName_LastName(String lastName);
}
英文:
I have an entity Person which has a property Name. Name is not marked as entity. For the Name class I have an AttributeConverter which creates a full name by string concatenation of first and last name. So for the person entity the column name is of type String.
@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;
// ...
}
This works. But now I want to extend my person repository. I want to find persons by her lastName. But
List<Person> findByName_LastName(String lastName);
or
List<Person> findByNameLastName(String lastName);
does not work. I get the following exception:
PersonRepository.findByName_LastName(java.lang.String)! Illegal attempt to dereference path source [null.name] of basic type
How can I solve the problem? Thanks and regards
EDIT:
public interface PersonRepository extends CrudRepository<Person, Long>{
// The repository works without the findByName...
// List<Person> findByName_LastName(String lastName);
}
答案1
得分: 1
这在查询派生中不起作用,也不能起作用,因为通常情况下,在您的情况下,转换所应用的函数是不可逆的。这意味着为了让Spring Data实现这一点,它需要分析转换,反转它,即创建一组从数据库中存储的连接字符串生成名字和姓氏的函数,并使用Criteria API实现它。我认为很明显这是无法完成的。
如果您知道应该执行什么查询,请使用@Query
注释。
更好的解决方案是将姓氏单独存储在一个列中,这样可以很容易地访问它。
英文:
This doesn't work with query derivation and it can't work because in general and in your case the function applied by the conversion is not reversible. This means in order for Spring Data to implement this it would need to analyse the conversion, invert it, i.e. create a set of functions that produce the first name and last name from the concatenated String stored in the database, and implement it using the Criteria API. I think it is obvious this can't be done.
If you know what query should be executed use a @Query
annotation.
The better solution would be to store the lastname in a separate column so it can easily be accessed.
If
答案2
得分: 1
你将名字(firstname)和姓氏(lastname)视为数据库中的一列,因为你在 name
列上使用了属性转换器(Attribute converter)。因此,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;
英文:
You treat firstname and lastname as a column in database since you use Attribute converter for name
column. So JPA treats name
as a column of type Name
and can't do query on Name
object type field.
The better solution is to store firstname and lastname in a separate column so that you can query easily. But if you want make a field concat of firstname and lastname and query on concat field also then you can use @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;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论