我有一个有100个字段的表,我想把它分成3-4个表。在创建时,其中一个表的主键将变为外键,其余表的主键将变为主键。
我试过这样的方法
@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);
}它正在创建表,但将错误作为类xyz.Entity2没有定义IdClass
还查看了很少的引用,比如使用@MapsId。但不是解决方案对我有用。有投入吗?
谢谢
文卡塔·马杜
发布于 2021-11-05 19:48:04
我不知道您用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;
}这是只保存OneToOne关联引用的父类。这孩子将是这种关系的主人。
这是您的Entity2孩子:
@Entity
public class Entity2 implements Serializable {
@Id
private Long id;
private String value;
@MapsId
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "id")
private Entity1 entity1;
}正如您所说的,您将将您的主实体拼接成多个子实体,我继续使用另一个子实体来澄清我的观点:
@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注释告诉hibernate使用子类的id列将OneToOne关系映射到Entity1类。第一步是使用id执行关系映射所必需的。第二步需要将所有3个实体保存到同一事务中的数据库中。稍后再谈这个。
让我们看看现在如何将所有这些实体保存到数据库中。
@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类。它是由cascadeType=PERSIST参数保存的,我传递给了OneToOne注释操作。
这应该能够保存所有实体以及父实体。
注意:,我刚才提到了cascadeType=PERSIST,以及为什么它在这里很重要。如果不使用该方法,则必须显式调用Entity1存储库方法以将其对象保存到数据库中,然后可以将它们设置为子实体。但是如果这样做,hibernate将在对子实体执行保存操作时抛出:a different object with the same identifier value was already associated with the session异常。
发布于 2021-11-05 20:02:05
尝试使用@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);
}参考:共享主键
https://stackoverflow.com/questions/69856669
复制相似问题