Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么Hibernate为@manytone关联的隐式连接生成交叉连接?_Java_Sql_Database_Hibernate_Cross Join - Fatal编程技术网

Java 为什么Hibernate为@manytone关联的隐式连接生成交叉连接?

Java 为什么Hibernate为@manytone关联的隐式连接生成交叉连接?,java,sql,database,hibernate,cross-join,Java,Sql,Database,Hibernate,Cross Join,鲍尔和金在他们的书中说: 隐式联接总是沿着多对一或一对一关联进行,而不是通过集合值关联 [第646页,第14章] 但当我在代码中这样做时,它生成的是交叉连接,而不是内部连接 映射来自Member2(多对一)->CLub 但是Club2没有关于成员的信息,并且Member2具有Club2的外键 我的问题是 // Implicit: Find all UK club member who is female Transaction t1 = HibernateUtil.begin(); Query

鲍尔和金在他们的书中说:

隐式联接总是沿着多对一或一对一关联进行,而不是通过集合值关联

[第646页,第14章]

但当我在代码中这样做时,它生成的是交叉连接,而不是内部连接

映射来自
Member2
(多对一)->
CLub

但是
Club2
没有关于成员的信息,并且
Member2
具有Club2的外键

我的问题是

// Implicit: Find all UK club member who is female
Transaction t1 = HibernateUtil.begin();
Query query =
    HibernateUtil.getSession().createQuery("From Member2 m where m.club2.country = 'UK' ");
List<Member2> memList = query.list();
for (Member2 m : memList)
  System.out.println(m);
HibernateUtil.end(t1);
Club2.java

package com.lilu.de.onetomany.uni.other;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = "TBL_CLUB2")
public class Club2 {

  @GeneratedValue(generator = "pkey_Club2", strategy = GenerationType.SEQUENCE)
  @SequenceGenerator(name = "pkey_Club2", initialValue = 1000, allocationSize = 10,
      sequenceName = "seq_pkey_Club2")
  @Id
  private int club_id;

  private String club_name;

  private String country;

  // private Set Member2 = new HashSet();

  public Club2() {
    super();
  }

  public Club2(String cname, String ccountry) {
    this.club_name = cname;
    this.country = ccountry;
  }

  @Override
  public String toString() {
    String temp = club_name + " " + country + " ";
    // Iterator<Member2> iter = Member2.iterator();
    // String mems = null;
    // while (iter.hasNext()) {
    // mems += iter.next();
    // }
    // temp += "\n" + mems;
    return temp;
  }

  public int getClub_id() {
    return club_id;
  }

  public void setClub_id(int club_id) {
    this.club_id = club_id;
  }

  public String getClub_name() {
    return club_name;
  }

  public void setClub_name(String club_name) {
    this.club_name = club_name;
  }

  public String getCountry() {
    return country;
  }

  public void setCountry(String country) {
    this.country = country;
  }

  /*
   * public Set<Member2> getMember2() { return Member2; }
   * 
   * public void setMember2(Set<Member2> Member2) { this.Member2 = Member2; }
   */
}
hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
  ~ indicated by the @author tags or express copyright attribution
  ~ statements applied by the authors.  All third-party contributions are
  ~ distributed under license by Red Hat Inc.
  ~
  ~ This copyrighted material is made available to anyone wishing to use, modify,
  ~ copy, or redistribute it subject to the terms and conditions of the GNU
  ~ Lesser General Public License, as published by the Free Software Foundation.
  ~
  ~ This program is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
  ~ for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public License
  ~ along with this distribution; if not, write to:
  ~ Free Software Foundation, Inc.
  ~ 51 Franklin Street, Fifth Floor
  ~ Boston, MA  02110-1301  USA
  -->
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="connection.url">jdbc:postgresql://localhost:5432/hibernatedb1</property>
        <property name="connection.username">postgres</property>
        <property name="connection.password">ani155</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        <property name="format_sql">true</property> 

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>

        <!-- Names the annotated entity class -->
        <mapping class="com.lilu.de.onetomany.uni.other.Club2"/>
        <mapping class="com.lilu.de.onetomany.uni.other.Member2"/>
       <!--   <mapping class="com.apal.mapping.onetoone.User"/> -->
    </session-factory>

</hibernate-configuration>

org.postgresql.Driver
jdbc:postgresql://localhost:5432/hibernatedb1
博士后
ani155
1.
org.hibernate.dialogue.PostgreSqlDialogue
org.hibernate.cache.internal.NoCacheProvider
真的
真的
更新
Test.java

package com.lilu.de.onetomany.uni.other;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Test {
  public static void main(String[] args) {

    Test test = new Test();
    // test.setup();
    test.SelectQuery1Implicit();
    // test.SelectQuery2ExplicitFromClause();
    // test.SelectQuery3JoinFetch();
    // test.SelectQuery4ThetaJoin();
  }

  private void SelectQuery1Implicit() {
    // Implicit: Find all UK club member who is female
    Transaction t1 = HibernateUtil.begin();
    Query query =
        HibernateUtil.getSession().createQuery("From Member2 m where m.club2.country = 'UK' ");
    List<Member2> memList = query.list();
    for (Member2 m : memList)
      System.out.println(m);
    HibernateUtil.end(t1);
  }

  private void setup() {
    Transaction t1 = HibernateUtil.begin();
    Club2 c1 = new Club2("MulaRougne", "UK");
    Member2 m1 = new Member2("aaa", 25, 'm');
    Member2 m2 = new Member2("bbb", 28, 'f');
    m1.setClub2(c1);
    m2.setClub2(c1);
    HibernateUtil.getSession().save(c1);
    HibernateUtil.getSession().save(m1);
    HibernateUtil.getSession().save(m2);
    Club2 c2 = new Club2("Queen's Club", "UK");
    Club2 c3 = new Club2("Disney", "USA");
    Member2 m3 = new Member2("ccc", 32, 'm');
    Member2 m4 = new Member2("ddd", 23, 'm');
    m3.setClub2(c3);
    m4.setClub2(c3);
    HibernateUtil.getSession().save(m3);
    HibernateUtil.getSession().save(m4);
    HibernateUtil.getSession().save(c2);
    HibernateUtil.getSession().save(c3);


    /*
     * Club2 c1 = new Club2("MulaRougne", "UK"); Club2 c2 = new Club2("Queen's Club", "UK"); Club2
     * c3 = new Club2("Disney", "USA");
     * 
     * Member2 m1 = new Member2("aaa", 25, 'm'); Member2 m2 = new Member2("bbb", 28, 'f'); Member2
     * m3 = new Member2("ccc", 32, 'm'); Member2 m4 = new Member2("ddd", 23, 'm'); Member2 m5 = new
     * Member2("ee", 30, 'f');
     * 
     * c1.getMember2().add(m1); c1.getMember2().add(m2); c1.getMember2().add(m3);
     * 
     * c2.getMember2().add(m4); c2.getMember2().add(m5);
     * 
     * HibernateUtil.getSession().save(c2); HibernateUtil.getSession().save(m4);
     * HibernateUtil.getSession().save(m5);
     * 
     * HibernateUtil.getSession().save(c1); HibernateUtil.getSession().save(m1);
     * HibernateUtil.getSession().save(m2); HibernateUtil.getSession().save(m3);
     */
    HibernateUtil.end(t1);
  }


  private static class HibernateUtil {
    private static SessionFactory factory;
    private static Session session;
    static {
      factory = new Configuration().configure().buildSessionFactory();
    }

    public static Session getSession() {
      return session;
    }

    public static Transaction begin() {
      session = factory.openSession();
      return session.beginTransaction();
    }

    public static void end(Transaction tran) {
      tran.commit();
    }
  }
}
package com.lilu.de.onetomany.uni.other;
导入java.util.List;
导入org.hibernate.Query;
导入org.hibernate.Session;
导入org.hibernate.SessionFactory;
导入org.hibernate.Transaction;
导入org.hibernate.cfg.Configuration;
公开课考试{
公共静态void main(字符串[]args){
测试=新测试();
//test.setup();
test.SelectQuery1Implicit();
//test.SelectQuery2ExplicitFromClause();
//test.选择query3joinfetch();
//测试。选择query4thetajoin();
}
私有void selectquery1隐式(){
//隐式:查找所有英国俱乐部女性成员
事务t1=HibernateUtil.begin();
查询=
HibernateUtil.getSession().createQuery(“From Member2 m,其中m.club2.country='UK'”);
List memList=query.List();
对于(成员2 m:memList)
系统输出打印项次(m);
冬眠结束(t1);
}
私有无效设置(){
事务t1=HibernateUtil.begin();
俱乐部2 c1=新俱乐部2(“英国穆拉鲁涅”);
成员2 m1=新成员2(“aaa”,25,“m”);
成员2 m2=新成员2(“bbb”,28,“f”);
m1.setClub2(c1);
m2.集合2(c1);
HibernateUtil.getSession().save(c1);
HibernateUtil.getSession().save(m1);
HibernateUtil.getSession().save(m2);
Club2 c2=新俱乐部2(“女王俱乐部”、“英国”);
Club2 c3=新的Club2(“迪士尼”,“美国”);
成员2 m3=新成员2(“ccc”,32,“m”);
成员2 m4=新成员2(“ddd”,23,“m”);
m3.setClub2(c3);
m4.集合2(c3);
HibernateUtil.getSession().save(m3);
HibernateUtil.getSession().save(m4);
HibernateUtil.getSession().save(c2);
HibernateUtil.getSession().save(c3);
/*
*俱乐部2 c1=新俱乐部2(“英国穆拉鲁涅”);俱乐部2 c2=新俱乐部2(“英国女王俱乐部”);俱乐部2
*c3=新俱乐部2(“迪士尼”、“美国”);
* 
*成员2 m1=新成员2(“aaa”,25,“m”);成员2 m2=新成员2(“bbb”,28,“f”);成员2
*m3=新成员2(“ccc”,32,“m”);成员2 m4=新成员2(“ddd”,23,“m”);成员2 m5=新成员
*成员2(“ee”,30,“f”);
* 
*c1.getMember2().add(m1);c1.getMember2().add(m2);c1.getMember2().add(m3);
* 
*c2.getMember2().add(m4);c2.getMember2().add(m5);
* 
*HibernateUtil.getSession().save(c2);HibernateUtil.getSession().save(m4);
*HibernateUtil.getSession().save(m5);
* 
*HibernateUtil.getSession().save(c1);HibernateUtil.getSession().save(m1);
*HibernateUtil.getSession().save(m2);HibernateUtil.getSession().save(m3);
*/
冬眠结束(t1);
}
私有静态类HibernateUtil{
私营静电厂;
非公开静态会议;
静止的{
工厂=新配置().configure().buildSessionFactory();
}
公共静态会话getSession(){
返回会议;
}
公共静态事务开始(){
session=factory.openSession();
return session.beginTransaction();
}
公共静态无效结束(事务传输){
trans.commit();
}
}
}

大多数数据库引擎都会使用WHERE子句优化交叉连接,但我更喜欢使用显式连接

交叉连接由
连接生成

where m.club2.country = 'UK'
为了避免第二次俱乐部查询,您可以按如下方式编写查询:

Query query = session.createQuery("""
        select m 
        from Member2 m
        join fetch m.club2 c
        where
           c.country = :country
        """, Member2.class)
.setParameter("country", "UK");

使用绑定参数而不是硬编码参数时,此查询将删除和辅助选择。

已尝试将HQL作为:
从Member2作为m内部连接m.club2作为c,其中c.country='UK'
有什么问题?where子句具有
where member2x0_u0.club_id=club2x1_ux1.club_id
,因此Hibernate正确地从成员的俱乐部检索。一切都很好。是的,Hib正在正确地检索数据,但它正在进行交叉连接,而不是内部连接。我们知道交叉连接是一种速度慢且占用内存的交叉积。不应该是做一个内部连接??这是我关心的问题。。谢谢你的回复。@我知道我们可以做一个ecplicit内部连接From子句。根据这本书,hib应该为隐式连接生成一个内部连接。这里没有发生什么让我惊讶,想知道我错过了什么?嘿,谢谢你的回答。我知道那件事。但你澄清了hib无法生成内部连接,这是令人惊讶的。我会再试一次。看到你的博客,它是一块宝石。谢谢你的欣赏。我希望你读得愉快。当然。我要把它全部印出来。所有的文章很快就会被编成一本书。请继续收看@EmmanuelOgoma如果你有一个新问题,把它当作一个实际问题来问
where m.club2.country = 'UK'
Query query = session.createQuery("""
        select m 
        from Member2 m
        join fetch m.club2 c
        where
           c.country = :country
        """, Member2.class)
.setParameter("country", "UK");