【发布时间】:2021-03-26 15:42:41
【问题描述】:
我的数据库中有大量数据,因此我决定迁移到 Hibernate。我的一张表(我们称之为“MyItem”)没有任何合适的 ID。它只包含一列“json”。
由于某种原因(与数据量有关),我无法迁移所有 MyItem 数据,因此它们都有一个新的唯一标识符。
我所做的是在该表中添加一个新的“标识符”列(所以两列:“json”和“标识符”),并在我的 Java 代码中声明了我的实体,使其看起来像这样:
@Entity
@Table
public class MyItem {
@Lob
private String json;
private String identifier;
public MyItem() {
}
public MyItem(String json) {
this.json = json;
}
public void setIdentifier(String id) {
//fake
}
@Id
public String getIdentifier() {
if (identifier == null) {
identifier = UUID.randomUUID().toString();
}
return identifier;
}
public String getJson() {
return json;
}
public void setJson(String json) {
this.json = json;
}
}
我可以正确地创建和访问我的新数据(新数据是使用 Id 生成的),但是只有当我通过 HQL 进行访问时,我才会努力访问最旧的数据(标识符列中包含 null 的数据)。
这是我执行查询的方式(当然,我为问题更改了一些东西,请忽略我的假“json”,当然不是json,只是为了示例):
String myJson = "6044c44a-dd17-40ca-b66b-cb9d29cf8a33-1-0-1";
Query<MyItem> query = statelessSession.createQuery("FROM MyItem WHERE json = :json", MyItem.class);
query.setParameter("json", myJson);
query.setFetchSize(FETCH_SIZE);
query.setReadOnly(true);
query.setLockMode("a", LockMode.NONE);
try (ScrollableResults MyItemList = query.scroll(ScrollMode.FORWARD_ONLY)) {
while (MyItemList.next()) {
MyItem myItem = (MyItem) MyItemList.get(0);
myItem.getJson());
}
}
我在 myItem.getJson(); 上得到一个 NPE;
这里是 Hibernate 跟踪:
14:55:58.263 [TileBuilderCallable_pool-11-thread-2] TRACE o.h.engine.query.spi.QueryPlanCache@157 - Located HQL query plan in cache (FROM MyItem WHERE json = :json)
14:55:58.264 [TileBuilderCallable_pool-11-thread-2] TRACE o.h.engine.query.spi.QueryPlanCache@157 - Located HQL query plan in cache (FROM MyItem WHERE json = :json)
14:55:58.264 [TileBuilderCallable_pool-11-thread-2] TRACE o.h.engine.query.spi.HQLQueryPlan@344 - Iterate: FROM MyItem WHERE json = :json
14:55:58.264 [TileBuilderCallable_pool-11-thread-3] TRACE o.h.r.j.i.AbstractLogicalConnectionImplementor@66 - Preparing to begin transaction via JDBC Connection.setAutoCommit(false)
14:55:58.264 [TileBuilderCallable_pool-11-thread-2] TRACE o.h.engine.spi.QueryParameters@325 - Named parameters: {json=6044c44a-dd17-40ca-b66b-cb9d29cf8a33-1-0-1}
14:55:58.264 [TileBuilderCallable_pool-11-thread-3] TRACE o.h.r.j.i.AbstractLogicalConnectionImplementor@68 - Transaction begun via JDBC Connection.setAutoCommit(false)
14:55:58.264 [TileBuilderCallable_pool-11-thread-3] TRACE o.h.r.t.b.j.i.JdbcResourceLocalTransactionCoordinatorImpl@172 - ResourceLocalTransactionCoordinatorImpl#afterBeginCallback
14:55:58.264 [TileBuilderCallable_pool-11-thread-3] DEBUG o.h.e.t.internal.TransactionImpl@56 - On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
14:55:58.264 [TileBuilderCallable_pool-11-thread-2] DEBUG org.hibernate.SQL@94 -
select
myit0_.identifier as identifi1_0_,
myit0_.json as json5_0_
from
MyItem myit0_
where
myit0_.json=?
14:55:58.264 [TileBuilderCallable_pool-11-thread-3] DEBUG o.h.e.t.internal.TransactionImpl@78 - begin
14:55:58.264 [TileBuilderCallable_pool-11-thread-3] DEBUG o.s.j.d.DriverManagerDataSource@144 - Creating new JDBC DriverManager Connection to [jdbc:com.db://localhost:1234/mydb]
14:55:58.264 [TileBuilderCallable_pool-11-thread-2] TRACE o.h.r.j.i.ResourceRegistryStandardImpl@68 - Registering statement [[Statement - handle 1 (Connection ID - 25769822844)]]
14:55:58.264 [TileBuilderCallable_pool-11-thread-2] TRACE o.h.e.j.internal.JdbcCoordinatorImpl@339 - Registering last query statement [[Statement - handle 1 (Connection ID - 25769822844)]]
14:55:58.264 [TileBuilderCallable_pool-11-thread-2] TRACE o.h.type.descriptor.sql.BasicBinder@65 - binding parameter [1] as [VARCHAR] - [6044c44a-dd17-40ca-b66b-cb9d29cf8a33-1-0-1]
14:55:58.264 [TileBuilderCallable_pool-11-thread-2] TRACE org.hibernate.loader.Loader@2034 - Bound [2] parameters total
14:55:58.266 [TileBuilderCallable_pool-11-thread-2] TRACE o.h.r.j.i.ResourceRegistryStandardImpl@196 - Registering result set [com.db.ResultSet@55612811]
14:55:58.266 [TileBuilderCallable_pool-11-thread-2] TRACE o.h.t.descriptor.sql.BasicExtractor@51 - extracted value ([identifi1_0_] : [VARCHAR]) - [null]
14:55:58.266 [TileBuilderCallable_pool-11-thread-2] DEBUG org.hibernate.loader.Loader@1532 - Result row: null
14:55:58.267 [TileBuilderCallable_pool-11-thread-2] TRACE org.hibernate.loader.Loader@1149 - Total objects hydrated: 0
我在这里唯一的想法是尝试/捕获 NPE,因此我通过添加标识符来动态迁移数据。还有其他更智能的方式来执行我的查询吗?
谢谢! :)
【问题讨论】:
-
请问,您是不是在尝试用 NULL 标识符更新旧记录以获得标识符?
-
@NgọcHy 这是我想做的事情之一,是的,但这实际上不是这个查询的目的——而是检索一些数据
-
据我所知,为了检索任何数据,必须有自己的标识符。所以在我看来,你应该首先尝试给他们一个标识符。这会让你更轻松