【发布时间】:2018-03-04 12:02:33
【问题描述】:
我有一个使用 Java 8 的 spring boot (1.5.4.RELEASE) 项目。我有一个实体,它的相关域类如下:
@Entity
@Table(name = "Foo", schema = "dbo")
public class FooEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id")
private int id;
@Column(name="Name")
private String name;
@Column(name="Type")
private String type;
@Column(name="Color")
private String color;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "Car")
private Car car;
//getter and setter
}
public class Foo {
private int id;
private String name;
private String type;
private String color;
private Car car;
//Constructors and getters
}
我想创建一个从数据库中获取此 Foo 对象的存储库,但仅在用户要求时获取复杂字段以防止不必要的连接语句。回购看起来像这样:
import static com.test.entities.QFooEntity.fooEntity;
import static com.test.entities.QCarEntity.carEntity;
@Repository
public class FooRepository {
private final JPAQuery<FooEntity> query = createQuery().from(fooEntity);
public FooRepository getFooByName(String name) {
query.where(fooEntity.name.eq(name));
return this;
}
public FooRepository withCar() {
query.leftJoin(fooEntity.car, carEntity).fetchJoin();
return this;
}
public Foo fetch() {
FooEntity entity = query.fetchOne();
return FooMapper.mapEntityToDomain().apply(entity);
}
}
因此,对 Foo 对象的准系统调用将返回具有除汽车字段之外的所有字段值的实体。如果用户想要汽车信息,那么他们必须明确调用withCar。
这是映射器:
public class FooMapper {
public static Function<FooEntity, Foo> mapEntityToDomain() {
return entity -> {
return new Foo(e.getId(), e.getName(), e.getType(), e.getColor(), e.getCar());
};
}
}
问题是当您执行e.getCar() 时,如果该值不存在(即存在代理),JPA 将出去为您获取它。我不希望出现这种情况。它只会抓取这些值并将它们映射到等效域,如果它不存在则null。
我听说过(并尝试过)的一个解决方案是调用em.detach(entity);,但是,这并没有按我的预期工作,因为当您尝试访问getCar 时它会引发异常,而且我也听说这是不是最佳实践。
所以我的问题是在 JPA 实体上使用构建器模式创建存储库的最佳方法是什么,并且在尝试映射时不让它调用数据库。
【问题讨论】:
-
你在使用
jta datasource?? -
你正在尝试做的事情非常可疑......如果你不想要这种功能,为什么要使用 Hibernate?
-
那里有很奇怪的存储库。只工作一次还是为每个查询创建新的存储库?
标签: java spring hibernate jpa spring-boot