首页 \ 问答 \ 为什么hibernate为了加载@OneToOne双向关联而执行两个查询?(Why hibernate perform two queries for eager load a @OneToOne bidirectional association?)

为什么hibernate为了加载@OneToOne双向关联而执行两个查询?(Why hibernate perform two queries for eager load a @OneToOne bidirectional association?)

我有实体A有一个B实体,B有一个带有@OneToOne双向关联的A。

现在,当我找到A记录时,hibernate用B上的左外连接执行两个查询,如下所示:

select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b;
select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b WHERE b.id=?

首先查询加载A和B字段,这是可以的,但为什么执行第二个查询来重新加载A? 我认为这个查询加载了B中的A内容,但是这个A很明显是包含B的A ...因此它已经加载了第一个查询,是不是真的?

- 编辑 -

实体A:

@Entity
public class A implements Serializable{
    // id and other ecc ecc
    @OneToOne
    @JoinColumn(name="id_b")
    B b;
}

实体B:

@Entity
public class B implements Serializable{
    // id and other ecc ecc
    @OneToOne(mappedBy="b")
    A a;
}

情况就是这样,findAll on A需要两个查询......为什么?


i have entity A that has-a B entity, and B has-a A with @OneToOne bidirectional association.

Now, when i findall A records, hibernate perform two queries with a left outer join on B, something like this:

select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b;
select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b WHERE b.id=?

First query load A and B fields and it is ok, but why perform second query to reload A? I think this query load the A content in B, but this A is obviusly the A that contains B... so its already loaded with first query, isn't true?

-- EDIT --

Entity A:

@Entity
public class A implements Serializable{
    // id and other ecc ecc
    @OneToOne
    @JoinColumn(name="id_b")
    B b;
}

Entity B:

@Entity
public class B implements Serializable{
    // id and other ecc ecc
    @OneToOne(mappedBy="b")
    A a;
}

This is the situation, and a findAll on A need two queries... why?


原文:https://stackoverflow.com/questions/3381521
更新时间:2023-07-14 17:07

最满意答案

有两种使用TSQL选择BLOB的方法:

SELECT * FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a

以及:

SELECT BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a

请注意FROM子句之后的相关名称,这是强制性的。

第二个版本可以用于UPDATE,如下例所示:

UPDATE MyTable 
SET blobField = 
   (SELECT BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a) 
WHERE (CriteriaField = @criteria)

对于部分更新,可以使用此MSDN文章中所述的SET .WRITE增变器,这里是语法:

UPDATE MyTable SET BlobField .WRITE (expression, @offset, @length) WHERE (CriteriaField = @criteria)

请注意,WRITE mutator只能用于NON-NULL字段。

事实上,通过将@offset设置为0并将@length设置为NULL(或实际长度),也可以将其用于执行完整更新(如果列不包含NULL),如下例所示:

DECLARE @tmp VARBINARY(MAX) --Change to the correct datatype here
SELECT @tmp = BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a
UPDATE MyTable SET BlobField .WRITE (@tmp, 0, NULL) WHERE (CriteriaField = @criteria)

There are two ways to SELECT a BLOB with TSQL:

SELECT * FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a

As well as:

SELECT BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a

Note the correlation name after the FROM clause, which is mandatory.

The second version can be used for a UPDATE as in the following example:

UPDATE MyTable 
SET blobField = 
   (SELECT BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a) 
WHERE (CriteriaField = @criteria)

For partial updates one can use the SET .WRITE mutator as described in this MSDN article, here is the syntax:

UPDATE MyTable SET BlobField .WRITE (expression, @offset, @length) WHERE (CriteriaField = @criteria)

Note that the WRITE mutator can only be used on NON-NULL fields.

In fact this can also be used to do a full update (if the column does not contain NULL), by setting @offset to 0 and @length to NULL (or to the actual length), as in the following example:

DECLARE @tmp VARBINARY(MAX) --Change to the correct datatype here
SELECT @tmp = BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a
UPDATE MyTable SET BlobField .WRITE (@tmp, 0, NULL) WHERE (CriteriaField = @criteria)

相关问答

更多
  • 有两种使用TSQL选择BLOB的方法: SELECT * FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a 以及: SELECT BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a 请注意FROM子句之后的相关名称,这是强制性的。 第二个版本可以用于UPDATE,如下例所示: UPDATE MyTable SET blobField = (SE ...
  • 只要LittleTable满足作为OUTPUT ... INTO目标的要求,就可以使用OUTPUT子句 UPDATE BigTable SET ExportedFlag = 'T' OUTPUT inserted.Col1, inserted.Col2 INTO LittleTable(Col1,Col2) WHERE 如果您使用INSERTED或DELETED ,则没有任何区别。 唯一不同的列是你正在更新的那个(已deleted.ExportedFlag具有之前的值并且i ...
  • 您可以使用带有JOIN UPDATE执行此操作。 像这样的东西: UPDATE t1 SET t1.Grouped = t2.Grouped FROM @WorkTable t1 INNER JOIN @Worktable t2 ON -- a condition WHERE -- you can also add conditions here You can do this using UPDATE with JOIN. Something like this: UPDATE t1 SET t1.Gr ...
  • UPDATE m SET m.name = m1.name FROM MyTable m JOIN MyTable1 m1 ON m.id = m1.id WHERE m.id = 1 UPDATE m SET m.name = m1.name FROM MyTable m JOIN MyTable1 m1 ON m.id = m1.id WHERE m.id = 1
  • 我在执行我的程序时遇到同样的问题。 Windows 2012和Windows 2007之间的MSXML2.HTTP方法似乎有所不同。例如,2012年发送的工作方式如下: DECLARE @send NVARCHAR(4000) = 'send("' + REPLACE(@requestBody, '"', '''') + '")'; EXEC @hResult = sp_OAMethod @objectID, @send 不像 sp_OAMethod @objectID, 'send', null, @ ...
  • 这应该接近你需要的。 可能需要处理连接条件,但我认为我从INSTR的转换将会这样做。 UPDATE i SET strFileProcesstype = fs.STRFILEPROCESSTYPE, strFileSignatureType = fs.strfilesignaturetype FROM tblitem i INNER JOIN tblFileSignature fs ON i.strfilesignature = LE ...
  • 有几种方法: EXEC sp_server_info 2 要么 SELECT @@version 要么 SELECT serverproperty('ProductVersion') 你也可以这样做: DECLARE @ver nvarchar(128) SET @ver = CAST(serverproperty('ProductVersion') AS nvarchar) SET @ver = SUBSTRING(@ver, 1, CHARINDEX('.', @ver) - 1) IF ( @v ...
  • 这是SQL Server中数据类型优先的经典案例。 Int始终具有比varchar更高的优先级。 你的第一个座位 在第一个块的update语句中,即使CASE语句的一个结果表达式具有int数据类型(在本例中为@passState),并且CASE语句的其余结果表达式求值为varchar数据类型,那么结果所有的表达式都应该是Int,因为Int优先于varchar。 但是,当CASE的其余结果表达式求值为varchar时,您将在第一个CASE结果表达式@passFName上获得语法错误,因为它期望为所有的int: ...
  • SELECT D.DiscountID FROM Discounts D LEFT JOIN TeamExclusiveDiscount T ON D.DiscountID=T.DiscountID WHERE T.TeamID=@TeamID OR T.TeamID IS NULL SQL测试的SQLFIDDLE SELECT D.DiscountID FROM Discounts D LEFT JOIN TeamExclusiveDiscount T ON D.Disc ...
  • CASE语句返回一个值,它不通过更改SQL查询充当IF语句(如果是,则执行此操作)。 您需要将where语句修改为以下内容: AND ( (@status = 99 AND v.idStatus NOT IN (5, 1, 4, 20)) OR (@status NOT IN (0, 99) AND v.idStatus = @status) ) 编辑:评论者是正确的,第二次检查需要确保@status不是99。 The CASE statement returns a ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)