我有两个类(class),Test2 和 Test3。 Test2 有一个属性 test3,它是 Test3 的一个实例。换句话说,我有一个单向的 OneToOne 关联,其中 test2 引用了 test3。
当我从数据库中选择 Test2 时,我可以看到正在进行单独的选择以获取关联的 test3 类的详细信息。这就是著名的 1+N 选择问题。
要解决此问题以使用单个选择,我正在尝试使用 fetch=join 注释,据我所知是 @Fetch(FetchMode.JOIN)
但是,在 fetch 设置为 join 的情况下,我仍然看到单独的选择。这是我设置的相关部分..
hibernate .cfg.xml:
<property name="max_fetch_depth">2</property>
测试 2:
public class Test2 {
@OneToOne (cascade=CascadeType.ALL , fetch=FetchType.EAGER)
@JoinColumn (name="test3_id")
@Fetch(FetchMode.JOIN)
public Test3 getTest3() {
return test3;
}
注意,出于绝望,我将 FetchType 设置为 EAGER,即使对于 OneToOne 映射它默认为 EAGER,但它没有任何区别。
感谢您的帮助!
编辑:我几乎已经放弃尝试使用 FetchMode.JOIN - 任何人都可以确认他们已经让它工作,即产生左外连接吗? 在文档中我看到“通常,映射文档不用于自定义提取。相反,我们保留默认行为,并为特定事务覆盖它,使用 HQL 中的左连接提取”
如果我改用左连接获取:
query = session.createQuery("from Test2 t2 left join fetch t2.test3");
然后我确实得到了我想要的结果 - 即查询中的左外连接。
编辑编号 2:
伙计们,非常感谢您的回复。现在我想弄个水落石出。我通常发现,当我调查某事时,我最终学到的东西比我想象的要多得多。
有一件事我已经学会了——我在旧版本的 hibernate 上运行,因为我没有意识到 maven 存储库已经过时了。现在我也连接到 jboss 存储库,并且我拥有最新版本的 hibernate 和 hibernate 注释 - 两种情况下都是 3.5.1-Final。
我已经设置了一个尽可能简化它的小测试用例 - 我仍然在 3.5.1-Final 中看到这个问题,虽然我 99% 确定这只是一些愚蠢的东西我是设置不正确,尤其是 Ross,因为你让它工作了(感谢你花时间顺便尝试一下)
所以我有这些类(class)(这次是全文)
A级
package com.play.hibernate2;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
@Entity
public class A {
private Integer id;
private B b;
public A() {
super();
}
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@OneToOne (cascade=CascadeType.ALL)
@Fetch(FetchMode.JOIN)
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
}
B级
package com.play.hibernate2;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class B {
private Integer id;
public B() {
super();
}
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
我的整个hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- <property name="connection.driver_class">com.p6spy.engine.spy.P6SpyDriver</property> -->
<property name="connection.url">jdbc:mysql://localhost:3306/play</property>
<property name="connection.username">play</property>
<property name="connection.password">play</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="generate_statistics">true</property>
<!--
<property name="cache.use_structured_entries">true</property>
<property name="cache.use_query_cache">true</property>
-->
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
<!-- I think this may fix my individual requests for OneToOne problem -->
<property name="max_fetch_depth">2</property>
<!-- <property name="default_batch_fetch_size">10</property> -->
</session-factory>
</hibernate-configuration>
测试类
package com.play.hibernate2;
import java.util.List;
import java.util.Map;
import org.hibernate.FlushMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class RunTests4 {
private SessionFactory sessionFactory;
public static void main(String[] args){
RunTests4 d = new RunTests4();
d.run3();
}
public void run3(){
Session session = getSession();
session.beginTransaction();
createEntities(session);
session.getTransaction().commit();
System.out.println("NOW WITH A NEW TRANSACTION");
session = getSession();
session.beginTransaction();
Query query = session.createQuery("from A");
List results = query.list();
for (int i=0; i<results.size(); i++){
System.out.println("Row "+i+" was:");
A a = (A)results.get(i);
System.out.println("Result "+i);
System.out.println(a.toString());
}
session.getTransaction().commit();
}
public void createEntities(Session session){
for (int i=0; i<2; i++){
A a = new A();
B b = new B();
a.setB(b);
session.save(a);
}
}
public Session getSession(){
if (sessionFactory == null){
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass(A.class);
config.addAnnotatedClass(B.class);
config.configure();
new SchemaExport(config).create(true,true);
sessionFactory = config.buildSessionFactory();
}
Session session = sessionFactory.getCurrentSession();
return session;
}
}
最后的日志输出显示了额外的选择以取回关联的类
2 [main] INFO org.hibernate.cfg.annotations.Version - Hibernate Annotations 3.5.1-Final
23 [main] INFO org.hibernate.cfg.Environment - Hibernate 3.5.1-Final
28 [main] INFO org.hibernate.cfg.Environment - hibernate.properties not found
32 [main] INFO org.hibernate.cfg.Environment - Bytecode provider name : javassist
37 [main] INFO org.hibernate.cfg.Environment - using JDK 1.4 java.sql.Timestamp handling
160 [main] INFO org.hibernate.annotations.common.Version - Hibernate Commons Annotations 3.2.0.Final
176 [main] INFO org.hibernate.cfg.Configuration - configuring from resource: /hibernate.cfg.xml
176 [main] INFO org.hibernate.cfg.Configuration - Configuration resource: /hibernate.cfg.xml
313 [main] INFO org.hibernate.cfg.Configuration - Configured SessionFactory: null
338 [main] INFO org.hibernate.dialect.Dialect - Using dialect: org.hibernate.dialect.MySQLDialect
462 [main] INFO org.hibernate.cfg.AnnotationBinder - Binding entity from annotated class: com.play.hibernate2.Test2
545 [main] INFO org.hibernate.cfg.annotations.EntityBinder - Bind entity com.play.hibernate2.Test2 on table Test2
649 [main] INFO org.hibernate.cfg.AnnotationBinder - Binding entity from annotated class: com.play.hibernate2.Test3
650 [main] INFO org.hibernate.cfg.annotations.EntityBinder - Bind entity com.play.hibernate2.Test3 on table Test3
651 [main] INFO org.hibernate.cfg.AnnotationBinder - Binding entity from annotated class: com.play.hibernate2.A
651 [main] INFO org.hibernate.cfg.annotations.EntityBinder - Bind entity com.play.hibernate2.A on table A
653 [main] INFO org.hibernate.cfg.AnnotationBinder - Binding entity from annotated class: com.play.hibernate2.B
653 [main] INFO org.hibernate.cfg.annotations.EntityBinder - Bind entity com.play.hibernate2.B on table B
678 [main] INFO org.hibernate.cfg.AnnotationConfiguration - Hibernate Validator not found: ignoring
687 [main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - Running hbm2ddl schema export
688 [main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - exporting generated schema to database
691 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Using Hibernate built-in connection pool (not for production use!)
691 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Hibernate connection pool size: 1
698 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - autocommit mode: false
711 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost:3306/play
711 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - connection properties: {user=play, password=****}
alter table A
drop
foreign key FK412E010759
alter table Test2
drop
foreign key FK4CF5DC04B7E1B79
drop table if exists A
drop table if exists B
drop table if exists Test2
drop table if exists Test3
create table A (
id integer not null auto_increment,
b_id integer,
primary key (id)
)
create table B (
id integer not null auto_increment,
primary key (id)
)
create table Test2 (
id integer not null auto_increment,
name varchar(255),
value integer not null,
test3_id integer,
primary key (id)
)
create table Test3 (
id integer not null auto_increment,
name varchar(255),
value integer not null,
primary key (id)
)
alter table A
add index FK412E010759 (b_id),
add constraint FK412E010759
foreign key (b_id)
references B (id)
alter table Test2
add index FK4CF5DC04B7E1B79 (test3_id),
add constraint FK4CF5DC04B7E1B79
foreign key (test3_id)
references Test3 (id)
2562 [main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - schema export complete
2564 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - cleaning up connection pool: jdbc:mysql://localhost:3306/play
2571 [main] INFO org.hibernate.cfg.search.HibernateSearchEventListenerRegister - Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.
2575 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Using Hibernate built-in connection pool (not for production use!)
2575 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - Hibernate connection pool size: 1
2575 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - autocommit mode: false
2575 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost:3306/play
2575 [main] INFO org.hibernate.connection.DriverManagerConnectionProvider - connection properties: {user=play, password=****}
2622 [main] INFO org.hibernate.cfg.SettingsFactory - RDBMS: MySQL, version: 5.1.30
2622 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.1.9 ( Revision: ${svn.Revision} )
2633 [main] INFO org.hibernate.dialect.Dialect - Using dialect: org.hibernate.dialect.MySQLDialect
2635 [main] INFO org.hibernate.engine.jdbc.JdbcSupportLoader - Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
2636 [main] INFO org.hibernate.transaction.TransactionFactoryFactory - Using default transaction strategy (direct JDBC transactions)
2638 [main] INFO org.hibernate.transaction.TransactionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
2638 [main] INFO org.hibernate.cfg.SettingsFactory - Automatic flush during beforeCompletion(): disabled
2638 [main] INFO org.hibernate.cfg.SettingsFactory - Automatic session close at end of transaction: disabled
2638 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch size: 15
2638 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC batch updates for versioned data: disabled
2638 [main] INFO org.hibernate.cfg.SettingsFactory - Scrollable result sets: enabled
2638 [main] INFO org.hibernate.cfg.SettingsFactory - JDBC3 getGeneratedKeys(): enabled
2638 [main] INFO org.hibernate.cfg.SettingsFactory - Connection release mode: auto
2639 [main] INFO org.hibernate.cfg.SettingsFactory - Maximum outer join fetch depth: 2
2639 [main] INFO org.hibernate.cfg.SettingsFactory - Default batch fetch size: 1
2639 [main] INFO org.hibernate.cfg.SettingsFactory - Generate SQL with comments: enabled
2639 [main] INFO org.hibernate.cfg.SettingsFactory - Order SQL updates by primary key: disabled
2639 [main] INFO org.hibernate.cfg.SettingsFactory - Order SQL inserts for batching: disabled
2639 [main] INFO org.hibernate.cfg.SettingsFactory - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
2641 [main] INFO org.hibernate.hql.ast.ASTQueryTranslatorFactory - Using ASTQueryTranslatorFactory
2641 [main] INFO org.hibernate.cfg.SettingsFactory - Query language substitutions: {}
2641 [main] INFO org.hibernate.cfg.SettingsFactory - JPA-QL strict compliance: disabled
2641 [main] INFO org.hibernate.cfg.SettingsFactory - Second-level cache: enabled
2641 [main] INFO org.hibernate.cfg.SettingsFactory - Query cache: disabled
2644 [main] INFO org.hibernate.cfg.SettingsFactory - Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
2644 [main] INFO org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge - Cache provider: org.hibernate.cache.NoCacheProvider
2644 [main] INFO org.hibernate.cfg.SettingsFactory - Optimize cache for minimal puts: disabled
2644 [main] INFO org.hibernate.cfg.SettingsFactory - Structured second-level cache entries: disabled
2648 [main] INFO org.hibernate.cfg.SettingsFactory - Echoing all SQL to stdout
2648 [main] INFO org.hibernate.cfg.SettingsFactory - Statistics: enabled
2649 [main] INFO org.hibernate.cfg.SettingsFactory - Deleted entity synthetic identifier rollback: disabled
2649 [main] INFO org.hibernate.cfg.SettingsFactory - Default entity-mode: pojo
2649 [main] INFO org.hibernate.cfg.SettingsFactory - Named query checking : enabled
2649 [main] INFO org.hibernate.cfg.SettingsFactory - Check Nullability in Core (should be disabled when Bean Validation is on): enabled
2697 [main] INFO org.hibernate.impl.SessionFactoryImpl - building session factory
2796 [Finalizer] INFO org.hibernate.connection.DriverManagerConnectionProvider - cleaning up connection pool: jdbc:mysql://localhost:3306/play
2929 [main] INFO org.hibernate.impl.SessionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured
Hibernate:
/* insert com.play.hibernate2.B
*/ insert
into
B
values
( )
Hibernate:
/* insert com.play.hibernate2.A
*/ insert
into
A
(b_id)
values
(?)
Hibernate:
/* insert com.play.hibernate2.B
*/ insert
into
B
values
( )
Hibernate:
/* insert com.play.hibernate2.A
*/ insert
into
A
(b_id)
values
(?)
NOW WITH A NEW TRANSACTION
Hibernate:
/*
from
A */ select
a0_.id as id2_,
a0_.b_id as b2_2_
from
A a0_
Hibernate:
/* load com.play.hibernate2.B */ select
b0_.id as id3_0_
from
B b0_
where
b0_.id=?
Hibernate:
/* load com.play.hibernate2.B */ select
b0_.id as id3_0_
from
B b0_
where
b0_.id=?
Row 0 was:
Result 0
com.play.hibernate2.A@351daa0e
Row 1 was:
Result 1
com.play.hibernate2.A@2e879860
编辑数字 3:
如果我按 Ross 的方式做事,在加载时,将创建一个左外连接。如果我用列表来做,会发出单独的选择。这是相关的代码。只有改变它才能重现行为上的差异:
/* generates the left outer join
A a = (A)session.load(A.class,1);
System.out.println(a.getId()+" = "+a.getB().getName());
*/
// Creates separate selects for each object b associated with each a
Query query = session.createQuery("from A");
List results = query.list();
A a = (A)results.get(0);
System.out.println(a.getId()+" = "+a.getB().getName());
我猜它可能被称为“错误”。正如我之前提到的,在文档中,他们说在 HQL 中而不是在映射中指定获取模式是“常见的”,我认为这可能意味着 HQL 方式有更多的人流量来解决它。 .?
(顺便说一下,我向 A 和 B 添加了一个额外的“名称”字段,否则 hibernate 会优化检索,因为它可以仅从 A 上的外键获取所有 B)
最佳答案
作为蒸馏:
如果您使用 Query 接口(interface)(例如:session.createQuery()),@Fetch(JOIN) 将被忽略,但如果您使用 Criteria 接口(interface),它将被正确使用。
这实际上是 Hibernate 中的一个错误,从未被解决。不幸的是,很多应用程序使用 Query 接口(interface),无法轻松迁移到 Criteria 接口(interface)。
如果您使用查询接口(interface),您总是必须手动将 JOIN FETCH 语句添加到 HQL 中。
关于java - 在 Hibernate 中使用@Fetch(FetchMode.Join),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2931936/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po