spring-数据:外键为主
spring-data: foreign-key as a primary
我有一个包含 100 个字段的 table,我想将其分成 3-4 个 table。创建时,table 之一的主键将成为剩余 table 的外键和主键。
我试过这样的东西
@Entity
public class Entity1 implements Serializable {
@Id
@Column(name = "id")
private String id;
...
}
@Entity
@IdClass(Entity1.class)
public class Entity2 implements Serializable {
@Id
@OneToOne
@JoinColumn(name = "id", referencedColumnName = "id")
private Entity1 id;
...
}
@Repository
public interface Entity1Repository extends JpaRepository<Entity1, String> {
Optional<Entity1> findById(String id);
}
@Repository
public interface Entity2Repository extends JpaRepository<Entity2, Entity1> {
Optional<Entity2> findById(Entity1 id);
}
它正在创建 tables,但给出错误 This class [class xyz.Entity2] 没有定义 IdClass
还查看了一些参考资料,例如 @MapsId 的使用。但是没有一个解决方案对我有用。有任何输入吗?
谢谢
文卡塔马杜
我不知道您在使用 MapsId
功能时尝试了哪种方法。但在这种情况下它肯定可以帮助你。以下是 MapsId
实现的示例代码:
@Entity
public class Entity1 implements Serializable {
@Id
private Long id;
private String name;
@OneToOne(mappedBy = "entity1")
private Entity2 entity2;
@OneToOne(mappedBy = "entity1")
private Entity3 entity3;
}
这是 parent class,它将只保存 OneToOne
关联的引用。 child 将成为关系的所有者。
这是你的 Entity2 child:
@Entity
public class Entity2 implements Serializable {
@Id
private Long id;
private String value;
@MapsId
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "id")
private Entity1 entity1;
}
正如您所说,您会将主要实体拼接成多个 child 我继续使用另一个 child 实体来阐明我的观点:
@Entity
public class Entity3 implements Serializable {
@Id
private Long id;
private String value;
@MapsId
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "id")
private Entity1 entity1;
}
你现在可能已经注意到我正在使用:
@JoinColumn
child classes 中的注解告诉 hibernate 使用 child 的 id 列将此 OneToOne
关系映射到 Entity1
class.
- 我在 child classes 中使用 cascadeType = PERSIST。
第一步需要做id的关系映射。第二步需要在同一事务中将所有 3 个实体保存到数据库中。稍后会详细介绍。
Let's see how you can now save all of these entities into the database.
@Transactional
public void saveEntities() {
Long id = 1L;
Entity1 entity1 = new Entity1();
entity1.setId(id);
entity1.setName("Test1Entity1: " + id);
Entity2 entity2 = new Entity2();
entity2.setValue("entity2Value: " + id);
entity2.setEntity1(entity1);
entity2Repository.save(entity2);
Entity3 entity3 = new Entity3();
entity3.setValue("Test3Entity:" + id);
entity3.setEntity1(entity1);
entity3Repository.save(entity3);
}
请注意,我没有将 Entity1
class 保存到存储库中。它由我传递给 OneToOne
注释操作的 cascadeType=PERSIST
参数保存。
This should be able to save all the entities along with the parent one.
注意: 之前我说过 cascadeType=PERSIST 以及为什么它在这里很重要。如果您不使用它,那么您必须首先显式调用 Entity1
存储库方法以将其 object 保存到数据库,然后您可以将它们设置到 child 实体中。但是如果你这样做,当你对 child 实体执行保存操作时,hibernate 会抛出:a different object with the same identifier value was already associated with the session
异常。
尝试使用 @PrimaryKeyJoinColumn
:
@Entity
public class Entity1 {
@Id
@Column(name = "id")
private String id;
...
@OneToOne(mappedBy = "entity1")
@PrimaryKeyJoinColumn
private Entity2 entity2;
}
@Entity
public class Entity2 {
@Id
@Column(name = "entity1_id")
private String id;
...
@MapsId
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "entity1_id)
private Entity1 entity1;
}
public interface Entity2Repository extends JpaRepository<Entity2, String>
测试:
@Test
void save() {
Entity1 entity1 = new Entity1();
entity1.setId("iddddd");
Entity2 entity2 = new Entity2();
detail.setEntity1(entity1);
this.entity2Repository.save(entity2);
}
我有一个包含 100 个字段的 table,我想将其分成 3-4 个 table。创建时,table 之一的主键将成为剩余 table 的外键和主键。
我试过这样的东西
@Entity
public class Entity1 implements Serializable {
@Id
@Column(name = "id")
private String id;
...
}
@Entity
@IdClass(Entity1.class)
public class Entity2 implements Serializable {
@Id
@OneToOne
@JoinColumn(name = "id", referencedColumnName = "id")
private Entity1 id;
...
}
@Repository
public interface Entity1Repository extends JpaRepository<Entity1, String> {
Optional<Entity1> findById(String id);
}
@Repository
public interface Entity2Repository extends JpaRepository<Entity2, Entity1> {
Optional<Entity2> findById(Entity1 id);
}
它正在创建 tables,但给出错误 This class [class xyz.Entity2] 没有定义 IdClass
还查看了一些参考资料,例如 @MapsId 的使用。但是没有一个解决方案对我有用。有任何输入吗?
谢谢
文卡塔马杜
我不知道您在使用 MapsId
功能时尝试了哪种方法。但在这种情况下它肯定可以帮助你。以下是 MapsId
实现的示例代码:
@Entity
public class Entity1 implements Serializable {
@Id
private Long id;
private String name;
@OneToOne(mappedBy = "entity1")
private Entity2 entity2;
@OneToOne(mappedBy = "entity1")
private Entity3 entity3;
}
这是 parent class,它将只保存 OneToOne
关联的引用。 child 将成为关系的所有者。
这是你的 Entity2 child:
@Entity
public class Entity2 implements Serializable {
@Id
private Long id;
private String value;
@MapsId
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "id")
private Entity1 entity1;
}
正如您所说,您会将主要实体拼接成多个 child 我继续使用另一个 child 实体来阐明我的观点:
@Entity
public class Entity3 implements Serializable {
@Id
private Long id;
private String value;
@MapsId
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "id")
private Entity1 entity1;
}
你现在可能已经注意到我正在使用:
@JoinColumn
child classes 中的注解告诉 hibernate 使用 child 的 id 列将此OneToOne
关系映射到Entity1
class.- 我在 child classes 中使用 cascadeType = PERSIST。
第一步需要做id的关系映射。第二步需要在同一事务中将所有 3 个实体保存到数据库中。稍后会详细介绍。
Let's see how you can now save all of these entities into the database.
@Transactional
public void saveEntities() {
Long id = 1L;
Entity1 entity1 = new Entity1();
entity1.setId(id);
entity1.setName("Test1Entity1: " + id);
Entity2 entity2 = new Entity2();
entity2.setValue("entity2Value: " + id);
entity2.setEntity1(entity1);
entity2Repository.save(entity2);
Entity3 entity3 = new Entity3();
entity3.setValue("Test3Entity:" + id);
entity3.setEntity1(entity1);
entity3Repository.save(entity3);
}
请注意,我没有将 Entity1
class 保存到存储库中。它由我传递给 OneToOne
注释操作的 cascadeType=PERSIST
参数保存。
This should be able to save all the entities along with the parent one.
注意: 之前我说过 cascadeType=PERSIST 以及为什么它在这里很重要。如果您不使用它,那么您必须首先显式调用 Entity1
存储库方法以将其 object 保存到数据库,然后您可以将它们设置到 child 实体中。但是如果你这样做,当你对 child 实体执行保存操作时,hibernate 会抛出:a different object with the same identifier value was already associated with the session
异常。
尝试使用 @PrimaryKeyJoinColumn
:
@Entity
public class Entity1 {
@Id
@Column(name = "id")
private String id;
...
@OneToOne(mappedBy = "entity1")
@PrimaryKeyJoinColumn
private Entity2 entity2;
}
@Entity
public class Entity2 {
@Id
@Column(name = "entity1_id")
private String id;
...
@MapsId
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "entity1_id)
private Entity1 entity1;
}
public interface Entity2Repository extends JpaRepository<Entity2, String>
测试:
@Test
void save() {
Entity1 entity1 = new Entity1();
entity1.setId("iddddd");
Entity2 entity2 = new Entity2();
detail.setEntity1(entity1);
this.entity2Repository.save(entity2);
}