Spring Data JPA:按自定义类类型的成员列查找

huangapple go评论87阅读模式
英文:

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&lt;Person&gt; findByName_LastName(String lastName);

or

List&lt;Person&gt; 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&lt;Person, Long&gt;{
	// The repository works without the findByName...
    // List&lt;Person&gt; 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 = &quot;first_name&quot;)
private String firstName;

@Column(name = &quot;last_name&quot;)
private String lastName;

@Formula(value = &quot;CONCAT(last_name, first_name)&quot;)
private String name;

huangapple
  • 本文由 发表于 2020年4月6日 15:03:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/61054549.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定