Mysql 在Hibernate中使用@ManytoMany时,是否可以在提供程序创建的联接表中设置非主键

Mysql 在Hibernate中使用@ManytoMany时,是否可以在提供程序创建的联接表中设置非主键,mysql,hibernate,Mysql,Hibernate,假设它们是两个表: (1) 父项:父项id(PK)、父项名称、创建日期、更新日期 (2) 子项:子项id(PK)、子项名称、创建日期、更新日期 现在,在使用@manytomany时,将创建第三个表。让它成为: (3) 父母子女 在调用时,JPA提供者将使用主键(即父项id和子项id)创建一个联接表。我的问题是,我们是否有可能在更新或创建时使用@manytomany关系设置创建日期/更新日期列。更新:我研究了一下,发现人们已经创建了一个关联实体来解决这类问题。这样做有一些局限性,但最终结果看起来并

假设它们是两个表:

(1) 父项:父项id(PK)、父项名称、创建日期、更新日期

(2) 子项:子项id(PK)、子项名称、创建日期、更新日期

现在,在使用@manytomany时,将创建第三个表。让它成为: (3) 父母子女


在调用时,JPA提供者将使用主键(即父项id和子项id)创建一个
联接表。我的问题是,我们是否有可能在更新或创建时使用@manytomany关系设置创建日期/更新日期列。

更新:我研究了一下,发现人们已经创建了一个关联实体来解决这类问题。这样做有一些局限性,但最终结果看起来并不太可怕。不过,可能还有一些更好的设计方法,我还没有考虑过

Parent
实体将有一个映射到
ParentChild
关联实体的
OneToMany
映射。必须设置
mappedBy
属性以强制使用关联实体:

@Entity
public class Parent {
    @Id @GeneratedValue private Long id;

    @OneToMany(mappedBy="parent", cascade=CascadeType.ALL)
    private List<ParentChild> children = new ArrayList<ParentChild>();

    public void addChild(Child child, boolean teamLead) {
        ParentChild association = new ParentChild();
        association.setChild(child);
        association.setParent(this);
        association.setTeamLead(teamLead);
        children.add(association);
        child.setParent(this);
    }
    public Long getId() { return id; }

}
然后关联实体将具有对这两个实体的
manytone
引用,以及一个主键。由于
@MapsId
注释,关联引用使用与
主键相同的id字段

@Entity
public class ParentChild {
    @EmbeddedId
    private ParentChildKey id;

    @ManyToOne
    @MapsId("parentId")
    private Parent parent;

    @ManyToOne
    @MapsId("childId")
    private Child child;

    private boolean teamLead;

    public ParentChild() { id = new ParentChildKey(); }
    public boolean isTeamLead() { return teamLead; }
    public void setTeamLead(boolean teamLead) { this.teamLead = teamLead; }
    public Parent getParent() { return parent; }
    public void setParent(Parent parent) { this.parent = parent; id.setParentId(parent.getId());}
    public Child getChild() { return child; }
    public void setChild(Child child) { this.child = child; id.setChildId(child.getId());}

}
主键实体没有什么特别之处

@Embeddable
public class ParentChildKey implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long parentId;
    private Long childId;
    public Long getParentId() { return parentId; }
    public void setParentId(Long parentId) { this.parentId = parentId; }
    public Long getChildId() { return childId; }
    public void setChildId(Long childId) { this.childId = childId; }    
    ... getters and setters
}

所以,它为我做了一个插入和选择,没有太多的麻烦,但是你可以看到,仅仅为了一个额外的字段,它似乎有很多额外的工作。当然,额外字段(在本例中,
teamLead
)的存储效率很高,但我可以想象一种“角色”类型的配置,从长远来看,这种配置更易于使用并更有意义。

更新:我对其进行了一点研究,发现人们已经创建了一个关联实体来解决这类问题。这样做有一些局限性,但最终结果看起来并不太可怕。不过,可能还有一些更好的设计方法,我还没有考虑过

Parent
实体将有一个映射到
ParentChild
关联实体的
OneToMany
映射。必须设置
mappedBy
属性以强制使用关联实体:

@Entity
public class Parent {
    @Id @GeneratedValue private Long id;

    @OneToMany(mappedBy="parent", cascade=CascadeType.ALL)
    private List<ParentChild> children = new ArrayList<ParentChild>();

    public void addChild(Child child, boolean teamLead) {
        ParentChild association = new ParentChild();
        association.setChild(child);
        association.setParent(this);
        association.setTeamLead(teamLead);
        children.add(association);
        child.setParent(this);
    }
    public Long getId() { return id; }

}
然后关联实体将具有对这两个实体的
manytone
引用,以及一个主键。由于
@MapsId
注释,关联引用使用与
主键相同的id字段

@Entity
public class ParentChild {
    @EmbeddedId
    private ParentChildKey id;

    @ManyToOne
    @MapsId("parentId")
    private Parent parent;

    @ManyToOne
    @MapsId("childId")
    private Child child;

    private boolean teamLead;

    public ParentChild() { id = new ParentChildKey(); }
    public boolean isTeamLead() { return teamLead; }
    public void setTeamLead(boolean teamLead) { this.teamLead = teamLead; }
    public Parent getParent() { return parent; }
    public void setParent(Parent parent) { this.parent = parent; id.setParentId(parent.getId());}
    public Child getChild() { return child; }
    public void setChild(Child child) { this.child = child; id.setChildId(child.getId());}

}
主键实体没有什么特别之处

@Embeddable
public class ParentChildKey implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long parentId;
    private Long childId;
    public Long getParentId() { return parentId; }
    public void setParentId(Long parentId) { this.parentId = parentId; }
    public Long getChildId() { return childId; }
    public void setChildId(Long childId) { this.childId = childId; }    
    ... getters and setters
}

所以,它为我做了一个插入和选择,没有太多的麻烦,但是你可以看到,仅仅为了一个额外的字段,它似乎有很多额外的工作。当然,额外字段(在本例中,
teamLead
)的存储效率很高,但我可以想象一种“角色”类型的配置,从长远来看,这种配置更易于使用,也更有意义。

如果我理解清楚,您正试图通过创建或更新日期时间来链接父级和子级。这意味着您必须在创建和更新期间始终同步这些元素,然后将它们适当地连接起来,如:

SELECT
*
FROM
parent
LEFT JOIN child
    ON parent.create_date = child.create_date 
        OR parent.update_date = child.update_date;
无论如何,我会说这是不安全的,因为create_date和update_date不一定是明确的


关于

如果我理解清楚,您正试图通过创建或更新日期时间来链接父级和子级。这意味着您必须在创建和更新期间始终同步这些元素,然后将它们适当地连接起来,如:

SELECT
*
FROM
parent
LEFT JOIN child
    ON parent.create_date = child.create_date 
        OR parent.update_date = child.update_date;
无论如何,我会说这是不安全的,因为create_date和update_date不一定是明确的


关于

当您更新/创建家长时,您想在孩子身上设置创建/更新日期还是其他方式?感谢您的回复好友…在插入家长对孩子或孩子对家长时,我需要用创建/更新日期更新我的第三个表(家长对孩子)(基本上我们总是使用id“s代表@many-to-many,因此我需要知道是否可以使用其他列,此处创建\日期/更新\日期)您想在更新/创建父级时在子级上设置创建\日期/更新\日期还是以其他方式设置?感谢您的回复好友…在插入父级对子级或子级对父级时,我需要更新我的第三个表(父级\子级)使用create_date/update_date(基本上我们总是将id“s用于@many-to-many,所以我需要知道是否可以使用其他列,这里是create_date/update_date)谢谢,但我已经尝试过使用一对多和多对一,同时显式创建第三个表。然后它工作得很好,所以现在我尝试使用多对多,而不创建第三个表来处理这个场景…(是否可能(只是出于好奇))我想知道hibernate是否可以在不显式创建第三个表的情况下自己管理它谢谢,但我已经尝试过在显式创建第三个表时使用一对多和多对一。然后它工作正常,所以现在我尝试在不创建第三个表的情况下使用多对多来处理这个场景…(可能吗(出于好奇)我想知道hibernate是否能够在不显式创建第三个表的情况下自行管理。谢谢,我只想知道这件事是否可能,如果可能……做起来安全吗?Hanks我只想知道这件事是否可能,如果可能……做起来安全吗