我正在使用javax.persistence
和Spring,我有一个简单的实体类和一个简单的CrudRepository
,它们运行良好,直到我尝试添加自己的findByXXX()
方法。
我的实体类如下:
@Entity
public class Node
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column (name = "ID")
private Integer mID;
/** The node's activity. */
@Column (name = "Activity", nullable = false, length = 200)
private String mActivity;
// ... other properties.
public Integer getId() { return mID; }
public void setId(Integer id) { mID = id; }
public String getActivity() { return mActivity; }
public void setActivity(String activity) { mActivity = activity; }
...
}
您会注意到我在实例属性上使用了'm'前缀的命名约定。这适用于我的存储库,直到我添加自己的findByXXX()
方法。所以我可以使用标准的CRUD方法从数据存储中保存和检索Node
。
当我尝试添加自己的查询方法时,因此:
public interface NodeRepository extends CrudRepository<Node, Integer>
{
public List<Node> findByActivity(String activity);
}
我的系统中断了。特别是我的存储库的自动连接失败(请参阅本文末尾的堆栈跟踪)。运气比设计更多,我发现如果我修改我的节点类不再在属性上使用'm'前缀,问题就消失了。也就是说,以下代码有效:
@Entity
public class Node
{
...
/** The node's activity. */
@Column (name = "Activity", nullable = false, length = 200)
private String activity;
// ... other properties.
public String getActivity() { return activity; }
public void setActivity(final String activity) { this.activity = activity; }
...
}
当Spring构建findByActivity()
方法时,它会通过属性名称(例如Node
)搜索activity
bean,而不是属性方法(例如。{ {1}})。
有谁知道确实如此吗?如果是这样,有没有办法解决它,所以我可以保持我的命名惯例?我并不喜欢它,它只是我习惯的东西。
PS:我使用的是Spring 3.2.x和Java 7
已编辑以添加堆栈跟踪 - 程序正在getActivity(), setActivity()
SpringJUnit4ClassRunner:
答案 0 :(得分:0)
请参阅此处,了解有关如何解决查询的文档。
没有命名你的方法:
public List<Node> findByMActivity(String activity);
或将映射移动到Methods而不是字段,我能看到的唯一明显的方法是使用@Query实际注释此方法或在此方法引用的其他地方定义命名查询。
@Query("my custom query")
public List<Node> findByActivity(String activity);
要以更通用的方式执行此操作,我猜您会考虑覆盖或将自定义QueryResolver传递给:
org.springframework.data.jpa.repository.query.JpaQueryMethod
无论如何,为了让你的字段以“m”为前缀,所有看起来都很麻烦。
答案 1 :(得分:0)
虽然我喜欢@Alan Hay的回答,但另一种选择是添加一个&#34;服务&#34;层到您的解决方案。我以前做过这个,为了在模型层中创建CRUD操作的界面。
您可以使用所需的getter方法名称创建一个服务类,即findByActivity
,调用存储库类&#39; findByMActivity(...
方法。
这也允许您拥有包含所有可用CRUD方法的模型层,并且服务对象将仅使用与该特定服务相关的那些CRUD操作,即ActivityService。实际上,您可以为相同的数据创建多个接口,具体取决于对该数据执行的操作。
然后,您的服务层类可以具有对用户有意义的任何方法名称,即findByActivity vs findByMActivity。 Martin Fowler描述了services layer well。
您的解决方案可能不会要求额外的层,但它可能是一个额外的抽象,可以解决这样的接口问题,更改域变量名称的成本会更高。