Java 名称空间键上的Spring/JPA连接

Java 名称空间键上的Spring/JPA连接,java,spring,jpa,spring-data-jpa,spring-data,Java,Spring,Jpa,Spring Data Jpa,Spring Data,我正在为现有数据库创建Spring4/Spring数据应用程序。数据库结构和数据由封闭源代码软件定义 现有系统的一个方面是,您可以对系统中的任何其他项创建注释。这意味着,一篇文章、一个文档、一个媒体文件(系统中的所有实体)可以有任意数量的注释,并且每个注释正好针对系统中的一个实体。所有注释都在相同的表中 实现方法是,表comment中有一列comment\u for,该列包含一个连接/名称空间/前缀引用,指向它作为注释的实际实体。当前系统似乎只是通过在主键前面加上表名来构建联接查询: +----

我正在为现有数据库创建Spring4/Spring数据应用程序。数据库结构和数据由封闭源代码软件定义

现有系统的一个方面是,您可以对系统中的任何其他项创建注释。这意味着,一篇文章、一个文档、一个媒体文件(系统中的所有实体)可以有任意数量的注释,并且每个注释正好针对系统中的一个实体。所有注释都在相同的表中

实现方法是,表
comment
中有一列
comment\u for
,该列包含一个连接/名称空间/前缀引用,指向它作为注释的实际实体。当前系统似乎只是通过在主键前面加上表名来构建联接查询:

+----+-------------------+----------------+ | id | comment_for | comment | +----+-------------------+----------------+ | 1| article:12345 | This is nice...| | 2| document:42 | Cool doc! | +----+-------------------+----------------+ 我只需要单向的。我的实体(目前的
文章
文档
媒体文件
)应该拥有他们的评论集。我不需要注释来保留对实体的引用

有办法做到这一点吗?生成的SQL查询应该类似于

SELECT * FROM .... WHERE comment.comment_for = concat('<entityname>:', <entity>.id); 
从…中选择*。。。。其中comment.comment_for=concat(“:”,.id);
我查看了
@JoinColumn
,但我无法修改用于连接的值,只能修改列名。目前我唯一的解决方案是CommentRepository界面上的手动
@Query
s,它为我提供了某个实体/ID组合的所有注释的ArrayList。但是我想让评论自动加入我的商业实体


更新:看起来我可以将的
comment\u中的名称空间和id拆分为两个新列,而不会中断现有软件。现在这两列分别是
comment\u for_id
comment\u for_entityname

您还可以将comment\u拆分为只包含与实体类似的id。添加一个额外的类似于entity_type的列将允许您避免不同实体之间重复的id值

您还可以在实体和注释之间关系的所有者端使用@JoinColumn。在您的例子中,它看起来像是注释实体/表,因为每个实体都有许多注释

例如:

@Entity
@NamedQueries({ @NamedQuery(name = "Comments.findAll", query = "select o from Comments o") })
@IdClass(CommentsPK.class)
public class Comments implements Serializable {
    private static final long serialVersionUID = 4787438687752132432L;
    @Id
    @Column(name = "COMMENT_TEXT", nullable = false, length = 30)
    private String commentText;
    @Id
    @Column(name = "ENTITY_TYPE", nullable = false, length = 30)
    private String entityType;
    @ManyToOne
    @Id
    @JoinColumn(name = "COMMENT_FOR")
    private EntityDemo entityDemo;
请注意,我将所有三个字段的组合设置为主键,我不确定在您当前的设置中使用什么标准作为主键

下面是一个实体的示例。这些属性是为了演示而制作的

@Entity
@NamedQueries({ @NamedQuery(name = "EntityDemo.findAll", query = "select o from EntityDemo o") })
@Table(name = "ENTITY_DEMO")
public class EntityDemo implements Serializable {
    private static final long serialVersionUID = -8709368847389356776L;
    @Column(length = 1)
    private String data;
    @Id
    @Column(nullable = false)
    private BigDecimal id;
    @OneToMany(mappedBy = "entityDemo", cascade = { CascadeType.PERSIST, CascadeType.MERGE })
    private List<Comments> commentsList;
@实体
@namedquerys({@NamedQuery(name=“EntityDemo.findAll”,query=“从EntityDemo中选择o”))
@表(name=“实体\演示”)
公共类EntityDemo实现了可序列化{
私有静态最终长serialVersionUID=-8709368847389356776L;
@列(长度=1)
私有字符串数据;
@身份证
@列(nullable=false)
私有双十进制id;
@OneToMany(mappedBy=“entityDemo”,cascade={CascadeType.PERSIST,CascadeType.MERGE})
私人列表评论列表;

comment\u中的键值对的用途是什么?如果您的实体id与comment\u中的值完全匹配,应该可以解决您的问题。您可以修改表吗?您也可以将comment\u拆分为只包含与实体类似的id。添加额外的类似于列的实体类型可以避免重复的id值在不同的实体之间。我没有编写创建表/插入数据的软件,但他们使用它来附加/连接注释与任何其他实体。我喜欢实体类型的想法。这在Spring中是如何实现的。使用@JoinColumns?我必须看看是否可以使用存储过程来拆分注释,就像编写的系统一样s数据不在我的控制之下。您可以在实体和注释之间的关系的所有者端使用@JoinCoumn。在您的情况下,它看起来像是注释实体/表,因为每个实体都有许多注释。只要您能够使用一些PL/SQL创建一个新的修改过的结构,这应该是可行的elps!谢谢。如果你用相应的代码片段写一篇回复文章,我可以接受它作为解决方案。谢谢。我不确定你的映射是如何工作的。EntityDemo需要对注释进行单向引用,因为有14个不同的EntityDemo实体(文章、文档、媒体…).Comment不知道字段级别的EntityDEmo,可能只是作为字符串类型。您是否将不同类型的实体作为EntityDEmo对象的属性捕获?还是通过继承实现?关于Comment有实体演示,可能我没有正确理解问题,但我的想法是,如果您删除e前缀,仅包含id它可以是FK。该FK将指向与特定注释关联的实体。我知道您提到的这可能不可能,因为db结构是在其他地方管理的。我已更新了我的问题。外键是一个复合项,由id和id所在的实体组成在DB中创建内容的系统将对任何其他实体的所有评论使用单一评论表。如果我对ID为123的实体文章发表评论,我的帖子将保存在表
comment
中,并将
comment\u for
设置为
Article:123
。如果我对媒体文件发表评论,则评论位于同一评论表中但是将
注释设置为media\u file:123(123现在是media文件的ID,而不是文章)。
@Entity
@NamedQueries({ @NamedQuery(name = "EntityDemo.findAll", query = "select o from EntityDemo o") })
@Table(name = "ENTITY_DEMO")
public class EntityDemo implements Serializable {
    private static final long serialVersionUID = -8709368847389356776L;
    @Column(length = 1)
    private String data;
    @Id
    @Column(nullable = false)
    private BigDecimal id;
    @OneToMany(mappedBy = "entityDemo", cascade = { CascadeType.PERSIST, CascadeType.MERGE })
    private List<Comments> commentsList;