我创建一对一的关系,我希望有方法来获取相同的实体(Distributor.class),但是一个做懒惰的获取,另一个渴望。
@Entity
@Table
public class Distributor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String site;
@OneToOne(
mappedBy = "distributor",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.LAZY,
optional = false
)
private Location location;
public void setLocation(Location repositoryLocation) {
if (repositoryLocation == null) {
if (this.location != null) {
this.location.setDataProvider(null);
}
}
else {
repositoryLocation.setDataProvider(this);
}
this.location = repositoryLocation;
}
// getters/setters/constructor
}
}
@Entity
@Table(name = "location")
public class Location {
@Id
private Long id;
@Column(name = "country_code")
private String countryCode;
private Double longitude;
private Double latitude;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "id")
private Distributor distributor;
public Distributor getDistributor() {
return distributor;
}
public void setDistributor(Distributor distributor) {
this.distributor = distributor;
}
// other getters/setters
}
我遇到的最大问题是,Spring数据JPA似乎忽略了FetchType,并急切地获取所有相关表(基于相关线程和Spring数据JPA文档)。使用分发服务器获取数据的所有Spring数据存储库方法。通过两个选项,从分发服务器和位置中急切地获取位置。通过使用@NamedEntityGraph:
@Entity
@Table
@NamedEntityGraph(
name = "distributor-entity-graph",
attributeNodes = {
@NamedAttributeNode("location"),
}
)
public class Distributor {
//spring data jpa methods
@EntityGraph(value = "distributor-entity-graph", type = EntityGraph.EntityGraphType.LOAD)
Optional<Distributor> findById(Long id);
如果使用这样的图,我会在位置上得到一个左外连接,虽然这是一种更好的急加载类型,但仍然是急加载。
到目前为止,我发现的一切似乎都是糟糕的解决办法。有没有什么更简洁的方法可以做到这一点,或者(首先在性能方面)只是不创建关系,而是按需获取位置
?急于加载是一种气味,但当我获取单个分配器时,在大多数情况下我都想这样做,但在某些情况下我不想这样做,尤其是如果我获取findAll()。
Hibernate会忽略每个双向一对一映射的父端上的LAZY
,这些映射设置了mappdBy
(或者使用JoinColVIII
并且是可选的),因为它需要知道何时使用null或代理初始化字段。
你的问题是,即使你对孩子(Location
)使用MapsId
,家长仍然使用mappedBy
。
下面是如何实现延迟加载的双向关联(不过它也有缺点,请阅读到最后)。
家长
@Entity
public class TestParent {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "id")
private TestChild child;
}
孩子
字段不是强制性的,它是有点hacky,你可以忽略它,并在需要时使用存储库获取孩子-你知道它的id子
字段上指定任何级联(这将反映您持久化它们的方式,所以一直读到最后),否则持久化将失败,因为它无法将id分配给子实体。可选=false
是强制性的,否则无论如何都会被急切地获取。小孩
public class TestChild {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "id")
private TestParent parent;
}
这就是你对孩子的定义,没有什么重要的改变。
坚持
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
TestParent parent = new TestParent();
TestChild child = new TestChild();
parent.setChild(child);
child.setParent(parent);
em.persist(parent);
em.persist(child);
em.getTransaction().commit();
em.close();
由于父实体不再级联到子实体,因此必须单独持久化子实体。
阅读更多。
问题是,Spring HATEOAS和Spring Data Rest之间有什么区别? 我觉得两者都可以做同样的事情,Spring数据Rest(作为Spring数据的一部分)似乎更有活力。 https://github.com/spring-projects/spring-hateoas https://github.com/spring-projects/spring-data-rest 你什么
我无法解决这个问题。我得到了“线程中的异常”main”org.hibernate.LazyInitializationException:未能延迟初始化角色集合:org.sandy.domain.Location.items,没有会话或会话被关闭”我知道会话已关闭,但tx: notionation-drive@Transactional应该确保打开会话。它可以很好地与EAGER获取一起工作。哦,是
我正在遵循入门指南[1],但是我已经从配置设置中删除了MySQL和analytics的内容,因为我不打算使用任何分析函数。但是,scdf服务后来崩溃了,因为没有配置数据源。 好的,所以似乎仍然需要在scdf-config-kafka.yml[2]中配置数据源(尽管从阅读文档来看,我认为它只用于分析内容)。 但为了什么?数据源用于持久化Kafka消息,还是在节点之间建立云流消息? 我找不到任何关于大
我正在尝试迁移到Spring Data R2DBC,我找不到对Amazon Redshift数据库的支持,如果有支持,有人可以帮助我吗? 下面是spring文档url,它支持的数据库很少,但红移不在列表中。https://spring.io/projects/spring-data-r2dbc
spring-data-neo4j工件在获取资源时会导致向tinkerpop域发出拒绝访问警告。 我的pom.xml文件有以下相关依赖项: 运行maven时,我收到以下错误(仅提供前几行): 等等等等。 我尝试了几件运气不好的事情,例如: 将spring-data-neo4j pom中列出的3个tinkerpop项目的排除项添加到依赖项中 在我的任何pom文件或maven设置中都没有对任何repo
我还没有找到在QueryDSL中声明这种SQL的任何方法。我能够编写两个select语句,但是我仍然无法将它们与结合起来。 最后,我想检索一个与给定查询匹配的ID列表。通常,相交的数量可以是20或30左右,这取决于我要搜索的键/值对的数量。 有没有人知道如何使用QueryDSL执行类似的操作?