Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.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连接和对多个表的限制_Java_Hibernate_Hibernate Criteria - Fatal编程技术网

Java Hibernate连接和对多个表的限制

Java Hibernate连接和对多个表的限制,java,hibernate,hibernate-criteria,Java,Hibernate,Hibernate Criteria,我有三个表要用Hibernate或JPA查询 表结构 CREATE TABLE `product` ( `product_id` int(11) NOT NULL AUTO_INCREMENT, `insert_date` datetime NOT NULL, `last_update` datetime NOT NULL, ... PRIMARY KEY (`product_id`) ) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHA

我有三个表要用Hibernate或JPA查询

表结构

CREATE TABLE `product` (
  `product_id` int(11) NOT NULL AUTO_INCREMENT,
  `insert_date` datetime NOT NULL,
  `last_update` datetime NOT NULL,
  ...
  PRIMARY KEY (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8;

CREATE TABLE `language` (
  `language_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL,
  ...
  PRIMARY KEY (`language_id`),
  KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;


CREATE TABLE `product_description` (
  `product_id` int(11) unsigned NOT NULL,
  `language_id` int(11) unsigned NOT NULL,
  `name` varchar(255) NOT NULL,
  `description` text NOT NULL,
  `tag` text NOT NULL,
  `meta_title` varchar(255) NOT NULL,
  `meta_description` varchar(255) NOT NULL,
  `meta_keyword` varchar(255) NOT NULL,
  PRIMARY KEY (`product_id`,`language_id`),
  KEY `name` (`name`),
  KEY `product_language_idx` (`language_id`),
  CONSTRAINT `product_description` FOREIGN KEY (`product_id`) REFERENCES `product` (`product_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `product_language` FOREIGN KEY (`language_id`) REFERENCES `language` (`language_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Product     <OneToMany>     ProductDescription
Language    <ManyToOne>     ProductDescription
ProductDescription实体(id是ProductDescriptionPK类中的复合键):

首先,我使用了Hibernate和条件查询:

     Criteria criteria = getSession().createCriteria(Product.class,"p");
     criteria.createAlias("p.productDescriptions", "pd");
     criteria.createAlias("pd.languages", "l");
     criteria.add(Restrictions.eq("l.languageId", new Integer(1)));
     result = criteria.list();
但该代码检索此错误:

原因:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: “字段列表”中的未知列“l2\产品描述\语言\ id”

我的问题是什么?我如何执行这样的查询


非常感谢

我不完全理解您的数据模型。 我认为从
语言
的角度来看,
语言
产品描述
之间的关系应该是一对多的关系,但把它放在一边

已更新

实际上,Hibernate无法使用上面指出的注释正确映射关系。它试图在表
语言
中映射奇怪的manytone关系,但找不到以下字段:
productDescription\u language\u id
productDescription\u product\u id

我认为您的表的正确映射是:

语言实体

@Entity
public class Language {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="language_id", unique=true, nullable=false)
    private Long languageId;

    private String name;

    @OneToMany(fetch=FetchType.LAZY, mappedBy="language")
    private List<ProductDescription> productDescriptions = 
         new ArrayList<ProductDescription>();

    // Other fields + getters and setters
}
@Entity
@Table(name="product_description")
public class ProductDescription {

      @Embeddable
      public static class ProductDescriptionPK implements Serializable {

      private static final long serialVersionUID = 1L;

      @Column(name = "product_id")
      protected Long productId;

      @Column(name = "language_id")
      protected Long languageId;

      public ProductDescriptionPK() {
      }

      public ProductDescriptionPK(Long productId, Long languageId) {
        super();
        this.productId = productId;
        this.languageId = languageId;
     }

   }

   @EmbeddedId
   private ProductDescriptionPK id;

   private String description;

   @ManyToOne
   @JoinColumn(name="language_id", nullable=false, insertable=false, updatable=false)
   private Language language;

   @ManyToOne(fetch=FetchType.LAZY)
   @JoinColumn(name="product_id", nullable=false, insertable=false, updatable=false)
   private Product product;

  // Other fields + getters and setters
}
下面是一个工作示例,说明如何使用在问题中声明的实体来链接JPQL

    EntityManager em = emf.createEntityManager();

    // [UPDATED] QUERY
    String jpql = "SELECT p.id, pd.description FROM Product p "
                + "JOIN p.productDescriptions pd "
                + "JOIN pd.language l WHERE l.language_id = :idLanguage)";

    Query query = newEm.createQuery(jpql);
    query.setParameter("idLanguage", new Long(1));

    List<Object> resultList = query.getResultList();

    System.out.println( resultList.size() + " product(s) found:" );

    for (Object singleResult : resultList) {
         Object[] singleRow = (Object[]) singleResult;
         System.out.println(singleRow[0] + " " + singleRow[1]);
    }
我一直在阅读一些关于这个主题的文章和书籍,使用带有where子句的左连接fetch是无效的。引用Gavin King等人的“带Hibernate的Java持久性”: “查询
left join fetch i.bids b其中b.amount
…无效。您不能说,“加载
实例并初始化其投标集合,但只能使用具有特定金额的
Bid
实例”


希望这能有所帮助。

你为什么不试试JPQL呢?我想你可以很容易地完成你的查询。现在没有时间用JPQL测试你的示例中的rigth查询,但是这个答案可能对你有用。我同意你的看法。你能得到我的示例吗?呃,我认为链接后面有一个示例。你有产品ProductDescription语言。以及前面提到的链接go Category主题帖子。因此,对于具有多个联接和on join字段条件的查询,我必须使用createQuery?如果要使用JPQL定义查询,您需要使用createQuery。您可能可以定义一个条件,但需要更多的代码行。谢谢Rubio,但我使用的是Hibernate它无法处理此错误“on子句”中的未知列“languages2\u.productDescription\u language\u id”。pd.ProductDescriptions中的Languages属性是List@antonio我也使用了Hibernate。请更新上面的问题,添加表结构、每个表的含义和执行的查询。我将尝试修改我的答案是正确的。@antonio我已经更新了我的答案。请检查一下。我如何在我的DAO中使用EntityManager?我只创建了一个sessionFactory Spring Bean,所以我无法实例化EntityManager,你能解释它是如何工作的吗?@antonio你可以用会话替换EntityManager来创建查询。从你的工厂获取会话并调用session.createQuery。
     Criteria criteria = getSession().createCriteria(Product.class,"p");
     criteria.createAlias("p.productDescriptions", "pd");
     criteria.createAlias("pd.languages", "l");
     criteria.add(Restrictions.eq("l.languageId", new Integer(1)));
     result = criteria.list();
@Entity
public class Language {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="language_id", unique=true, nullable=false)
    private Long languageId;

    private String name;

    @OneToMany(fetch=FetchType.LAZY, mappedBy="language")
    private List<ProductDescription> productDescriptions = 
         new ArrayList<ProductDescription>();

    // Other fields + getters and setters
}
@Entity
@Table(name="product_description")
public class ProductDescription {

      @Embeddable
      public static class ProductDescriptionPK implements Serializable {

      private static final long serialVersionUID = 1L;

      @Column(name = "product_id")
      protected Long productId;

      @Column(name = "language_id")
      protected Long languageId;

      public ProductDescriptionPK() {
      }

      public ProductDescriptionPK(Long productId, Long languageId) {
        super();
        this.productId = productId;
        this.languageId = languageId;
     }

   }

   @EmbeddedId
   private ProductDescriptionPK id;

   private String description;

   @ManyToOne
   @JoinColumn(name="language_id", nullable=false, insertable=false, updatable=false)
   private Language language;

   @ManyToOne(fetch=FetchType.LAZY)
   @JoinColumn(name="product_id", nullable=false, insertable=false, updatable=false)
   private Product product;

  // Other fields + getters and setters
}
    EntityManager em = emf.createEntityManager();

    // [UPDATED] QUERY
    String jpql = "SELECT p.id, pd.description FROM Product p "
                + "JOIN p.productDescriptions pd "
                + "JOIN pd.language l WHERE l.language_id = :idLanguage)";

    Query query = newEm.createQuery(jpql);
    query.setParameter("idLanguage", new Long(1));

    List<Object> resultList = query.getResultList();

    System.out.println( resultList.size() + " product(s) found:" );

    for (Object singleResult : resultList) {
         Object[] singleRow = (Object[]) singleResult;
         System.out.println(singleRow[0] + " " + singleRow[1]);
    }
select
    product0_.product_id as col_0_0_,
    productdes1_.description as col_1_0_ 
from
    Product product0_ 
inner join
    product_description productdes1_ 
        on product0_.product_id=productdes1_.product_id 
inner join
    Language language2_ 
        on productdes1_.language_id=language2_.language_id 
where
    language2_.language_id=?