java - 如何在 Hibernate 中使用 inner join 语句

标签 java mysql sql hibernate

我在 MySQL 数据库中有两个表: 1. 具有一些设备特定值的设备表。 2.只有id值和name值的vendor表

现在,我想从设备表中获取两个值,型号名称和 vendor_id。但是为了显示 vendor_id,我想显示相应的供应商名称。 所以在 MySQL Workbench 中,这条语句运行良好,并向我显示了预期的结果,如 Model = N95 和 Vendor = Nokia

SELECT device.model, vendor.vendor from device inner join vendor on device.vendor_id = vendor.id

现在我正在使用 Hibernate 从表中获取值。

public List<Device> listDevices() {
    session = HibernateUtil.getSessionFactory().openSession();
    Transaction tx = null;
    try{
        tx = session.beginTransaction();
        String sql = "SELECT device.model, vendor.vendor from device inner join vendor on device.vendor_id = vendor.id";
        SQLQuery query = session.createSQLQuery(sql);
        query.addEntity(Device.class);
        List list = query.list();
        allDevices = new ArrayList();
        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            device = (Device) iterator.next();
            allDevices.add(device);
        }
        tx.commit();
    } catch (HibernateException e) {
        if(tx!=null) tx.rollback();
            e.printStackTrace();
    } finally {
        session.close();
        return allDevices;
    }
}

但这不起作用我得到了这个异常:

SEVERE:   Column 'id' not found.
SEVERE:   org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.loader.Loader.doList(Loader.java:2223)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
at org.hibernate.loader.Loader.list(Loader.java:2099)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:289)
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1695)
at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:142)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:152)
at com.vodafone.omisuite.model.DeviceData.listDevices(DeviceData.java:154)
at com.vodafone.omisuite.model.DeviceData.<init>(DeviceData.java:50)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:374)
at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:186)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:100)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:409)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:269)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:116)
at com.sun.el.parser.AstValue.getBase(AstValue.java:151)
at com.sun.el.parser.AstValue.getValue(AstValue.java:200)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIData.getValue(UIData.java:732)
at javax.faces.component.UIData.getDataModel(UIData.java:1811)
at javax.faces.component.UIData.setRowIndexWithoutRowStatePreserved(UIData.java:484)
at javax.faces.component.UIData.setRowIndex(UIData.java:473)
at com.sun.faces.renderkit.html_basic.TableRenderer.encodeBegin(TableRenderer.java:82)
at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:869)
at javax.faces.component.UIData.encodeBegin(UIData.java:1133)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1854)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:894)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:443)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.sql.SQLException: Column 'id' not found.
  at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:988)
 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:974)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:919)
at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1167)
at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2851)
at org.hibernate.type.IntegerType.get(IntegerType.java:28)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:163)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:154)
at org.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:1097)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:565)
at org.hibernate.loader.Loader.doQuery(Loader.java:701)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2220)
... 76 more

如果我使用以下语句代替它的工作,但它会显示 vendor_id 的 ID 值而不是相应的名称。

SELECT * from device inner join vendor on device.vendor_id = vendor.id

我为这两个表创建了 java 类和两个 *.hbm.xml 文件。在 hibernate.cfg.xml 文件中配置了两个映射。

谁能帮我解释一下我做错了什么,我该如何解决? 如果您对如何创建相应的 HQL 语句有任何建议,请随时发布 ;-)

这是通过 Hibernate 创建的设备类!

/**
* Device generated by hbm2java
*/
@Entity
@Table(name="device"
,catalog="myDB"
)
public class Device  implements java.io.Serializable {

private Integer id;
private String version;
private String shortname;
private int vendorId;
private String model;
private String platform;
private String appIconSize;
private String description;
private String uaProfile;
private byte[] image;
private String imageMimetype;
private int internetonly;
private int creator;
private int approvable;
private int approved;
private Date changed;

public Device() {
}


public Device(String shortname, int vendorId, String model, String platform, int  internetonly, int creator, int approvable, int approved, Date changed) {
    this.shortname = shortname;
    this.vendorId = vendorId;
    this.model = model;
    this.platform = platform;
    this.internetonly = internetonly;
    this.creator = creator;
    this.approvable = approvable;
    this.approved = approved;
    this.changed = changed;
}
public Device(String shortname, int vendorId, String model, String platform, String    appIconSize, String description, String uaProfile, byte[] image, String imageMimetype,  int  internetonly, int creator, int approvable, int approved, Date changed) {
   this.shortname = shortname;
   this.vendorId = vendorId;
   this.model = model;
   this.platform = platform;
   this.appIconSize = appIconSize;
   this.description = description;
   this.uaProfile = uaProfile;
   this.image = image;
   this.imageMimetype = imageMimetype;
   this.internetonly = internetonly;
   this.creator = creator;
   this.approvable = approvable;
   this.approved = approved;
   this.changed = changed;
}

 @Id @GeneratedValue(strategy=IDENTITY)

@Column(name="id", unique=true, nullable=false)
public Integer getId() {
    return this.id;
}

public void setId(Integer id) {
    this.id = id;
}

@Column(name="version")
public String getVersion() {
    return this.version;
}

public void setVersion(String version) {
    this.version = version;
}

@Column(name="shortname", nullable=false)
public String getShortname() {
    return this.shortname;
}

public void setShortname(String shortname) {
    this.shortname = shortname;
}

@Column(name="vendor_id", nullable=false)
public int getVendorId() {
    return this.vendorId;
}

public void setVendorId(int vendorId) {
    this.vendorId = vendorId;
}

@Column(name="model", nullable=false)
public String getModel() {
    return this.model;
}

public void setModel(String model) {
    this.model = model;
}

@Column(name="platform", nullable=false, length=7)
public String getPlatform() {
    return this.platform;
}

public void setPlatform(String platform) {
    this.platform = platform;
}

@Column(name="app_icon_size", length=10)
public String getAppIconSize() {
    return this.appIconSize;
}

public void setAppIconSize(String appIconSize) {
    this.appIconSize = appIconSize;
}

@Column(name="description")
public String getDescription() {
    return this.description;
}

public void setDescription(String description) {
    this.description = description;
}

@Column(name="ua_profile")
public String getUaProfile() {
    return this.uaProfile;
}

public void setUaProfile(String uaProfile) {
    this.uaProfile = uaProfile;
}

@Column(name="image")
public byte[] getImage() {
    return this.image;
}

public void setImage(byte[] image) {
    this.image = image;
}

@Column(name="image_mimetype", length=16)
public String getImageMimetype() {
    return this.imageMimetype;
}

public void setImageMimetype(String imageMimetype) {
    this.imageMimetype = imageMimetype;
}

@Column(name="internetonly", nullable=false)
public int getInternetonly() {
    return this.internetonly;
}

public void setInternetonly(int internetonly) {
    this.internetonly = internetonly;
}

@Column(name="creator", nullable=false)
public int getCreator() {
    return this.creator;
}

public void setCreator(int creator) {
    this.creator = creator;
}

@Column(name="approvable", nullable=false)
public int getApprovable() {
    return this.approvable;
}

public void setApprovable(int approvable) {
    this.approvable = approvable;
}

@Column(name="approved", nullable=false)
public int getApproved() {
    return this.approved;
}

public void setApproved(int approved) {
    this.approved = approved;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name="changed", nullable=false, length=19)
public Date getChanged() {
    return this.changed;
}

public void setChanged(Date changed) {
    this.changed = changed;
}

}

最佳答案

最简单的解决方案就是返回设备列表。这不是普通的 SQL,您在这里使用关联。默认情况下,ManyToOne 关联(您的情况)是急切的,您无需额外的努力即可获得它,即 device.getVendor().getVendor()。

如果你只想返回 2 个字符串,你可以返回 map:

select new map (device.model as model, vendor.vendor as vendor) from Model model, Vendor vendor where device.vendor = vendor

编辑:

您还必须创建协会。为此,请删除 vendorId 属性并像这样更改您的代码:

public class Device implements java.io.Serializable {
    ...
    private Vendor vendor;
    ...

    @ManyToOne
    @JoinColumn(name="vendor_id", nullable=false)
    public int getVendorId() {
        return this.vendorId;
    }
}

如果它解决了您的问题,请告诉我。

关于java - 如何在 Hibernate 中使用 inner join 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20300324/

相关文章:

java - Spring REST - 在更长的空闲时间之后,第一次调用需要很长时间(5-10 秒)

python - Flask-SQLAlchemy 在创建表之前创建架构

java - arraylist迭代器,不打印第一行

mysql - MySQL 中的 "Cannot add foreign key constraint"错误

mysql - 考勤 : Get time_in and time_out of flexible schedule Employees

java - StreamingFileSink 未将数据提取到 s3

java - 如何为程序只填充一次HashMap对象?

php - 在子查询中选择多行或逃避子查询

sql - 按月和季度分组并汇总前 11 个月

java - 使用 tweet4j 按位置获取推文