2017-03-04 108 views
1

目前我正在学习Hibernate的,所以我在下面的方法(MWE)创建的数据库在MySQL三个用表空指针异常HQL在MySQL休眠

create database `fakturowanie`; 
use `fakturowanie`; 

drop table if exists `wykupione_uslugi`; #table 'bought services' 
drop table if exists `uslugi`; #table 'services' 
drop table if exists `kontrahenci`; table 'contractors' 

create table `kontrahenci`(
`kontrahent_id` int unsigned auto_increment primary key, 
`nazwisko` varchar(80), #surname 
`imie` varchar(30), #name 
`firma_nazwa` varchar(100), #company name 
`nip_pesel` varchar(20) not null unique, #person ID 
`ulica_nr_mieszkania` varchar(100), #street 
`kod_pocztowy` varchar(6), #postal code 
`miejscowosc` varchar(30), #city 
`sposob_zaplaty` varchar(7) not null default 'gotówka', #payment method default cash 
`uwzglednij_numer_faktury` bool not null default true, #include invoice number 
`alias` varchar(30) not null 
)engine = InnoDB 
default charset = utf8 
collate = utf8_polish_ci; 

create table `uslugi`(
`usluga_id` int unsigned auto_increment primary key, 
`nazwa` varchar(80) not null, #name 
`symbol_PKWIU/PKOB` varchar(10), 
`jednostka` varchar(10) not null, #unit 
`cena_jednostkowa_netto` decimal(6, 2) not null, #unit price 
`stawka_vat` int(2) unsigned not null #tax rate 
)engine = InnoDB 
default charset = utf8 
collate = utf8_polish_ci; 

create table `wykupione_uslugi`(
`id` int unsigned auto_increment primary key, 
`kontrahent_id` int unsigned not null, 
`usluga_id` int unsigned not null, 
foreign key(kontrahent_id) references kontrahenci(kontrahent_id), 
foreign key(usluga_id) references uslugi(usluga_id) 
)engine = InnoDB 
default charset = utf8 
collate = utf8_polish_ci; 

insert into `kontrahenci` (
nazwisko, imie, firma_nazwa, nip_pesel, ulica_nr_mieszkania, kod_pocztowy, miejscowosc,  sposob_zaplaty, uwzglednij_numer_faktury, alias) 
values ('Best', 'John', 'Best Inc.', 111-111-111, 'Best Street 5', 11-111, 'Best Valley', 'cash', 1, 'test'); 

insert into `uslugi` (
nazwa, jednostka, cena_jednostkowa_netto, stawka_vat) 
values (
'Best tutoring', 'hour', 1000.00, 0); 

insert into `wykupione_uslugi` (kontrahent_id, usluga_id) values (1, 1); 

我试图用做Hibernate是等价这个SQL查询

select 
`uslugi`.`nazwa`, 
`uslugi`.`symbol_PKWIU/PKOB`, 
`uslugi`.`jednostka`, 
`uslugi`.`cena_jednostkowa_netto`, 
`uslugi`.`stawka_vat` 
from 
`wykupione_uslugi` 
left join `kontrahenci` on `wykupione_uslugi`.`kontrahent_id` = `kontrahenci`.`kontrahent_id` 
left join `uslugi` on `wykupione_uslugi`.`usluga_id` = `uslugi`.`usluga_id` 
where 
`kontrahenci`.`alias` = 'test'; 

的我创建映射类是这样的:
Service

@Entity 
@Table(name="uslugi", schema = "fakturowanie") 
public class Service 
{ 
private int serviceID; 
private String serviceName; 
private String symbol; 
private String unit; 
private BigDecimal unitPrice; 
private int tax; 
private Collection<ServicesList> servicesLists; 

@Id 
@Column(name = "usluga_id", nullable = false) 
@GeneratedValue(generator="increment") 
@GenericGenerator(name="increment", strategy = "increment") 
public int getServiceID() 
{ 
    return serviceID; 
} 

public void setServiceID(int serviceID) 
{ 
    this.serviceID = serviceID; 
} 

@Basic 
@Column(name = "nazwa", nullable = false, length = 80) 
public String getServiceName() 
{ 
    return serviceName; 
} 

public void setServiceName(String serviceName) 
{ 
    this.serviceName = serviceName; 
} 

@Basic 
@Column(name = "symbol_PKWIU/PKOB", nullable = false, length = 10) 
public String getSymbol() 
{ 
    return symbol; 
} 

public void setSymbol(String symbol) 
{ 
    this.symbol = symbol; 
} 

@Basic 
@Column(name = "jednostka", nullable = false, length = 10) 
public String getUnit() 
{ 
    return unit; 
} 

public void setUnit(String unit) 
{ 
    this.unit = unit; 
} 

@Basic 
@Column(name = "cena_jednostkowa_netto", nullable = false, precision = 2) 
public BigDecimal getUnitPrice() 
{ 
    return unitPrice; 
} 

public void setUnitPrice(BigDecimal unitPrice) 
{ 
    this.unitPrice = unitPrice; 
} 

@Basic 
@Column(name = "stawka_vat", nullable = false) 
public int getTax() 
{ 
    return tax; 
} 

public void setTax(int tax) 
{ 
    this.tax = tax; 
} 

@OneToMany(mappedBy = "servicesMapping") 
public Collection<ServicesList> getServicesLists() 
{ 
    return servicesLists; 
} 

public void setServicesLists(Collection<ServicesList> servicesLists) 
{ 
    this.servicesLists = servicesLists; 
} 
} 

Contractor

@Entity 
@Table(name = "kontrahenci", schema = "fakturowanie") 
public class Contractor 
{ 
private int contractorID; 
private String surname; 
private String name; 
private String companyName; 
private String taxpayerINum; 
private String street; 
private String postalCode; 
private String city; 
private PaymentMethod paymentMethod; 
private byte includeInvoiceNum; 
private String alias; 
private Collection<ServicesList> servicesList; 

@Id 
@Column(name = "kontrahent_id", nullable = false) 
@GeneratedValue(generator="increment") 
@GenericGenerator(name="increment", strategy = "increment") 
public int getContractorID() 
{ 
    return contractorID; 
} 

public void setContractorID(int contractorID) 
{ 
    this.contractorID = contractorID; 
} 

@Basic 
@Column(name = "nazwisko", nullable = true, length = 80) 
public String getSurname() 
{ 
    return surname; 
} 

public void setSurname(String surname) 
{ 
    this.surname = surname; 
} 

@Basic 
@Column(name = "imie", nullable = true, length = 30) 
public String getName() 
{ 
    return name; 
} 

public void setName(String name) 
{ 
    this.name = name; 
} 

@Basic 
@Column(name = "firma_nazwa", nullable = true, length = 100) 
public String getCompanyName() 
{ 
    return companyName; 
} 

public void setCompanyName(String companyName) 
{ 
    this.companyName = companyName; 
} 

@Basic 
@Column(name = "nip_pesel", unique = true, length = 20, nullable = false) 
public String getTaxpayerINum() 
{ 
    return taxpayerINum; 
} 

public void setTaxpayerINum(String taxpayerINum) 
{ 
    this.taxpayerINum = taxpayerINum; 
} 

@Basic 
@Column(name = "ulica_nr_mieszkania", nullable = true, length = 100) 
public String getStreet() 
{ 
    return street; 
} 

public void setStreet(String street) 
{ 
    this.street = street; 
} 

@Basic 
@Column(name = "kod_pocztowy", nullable = true, length = 6) 
public String getPostalCode() 
{ 
    return postalCode; 
} 

public void setPostalCode(String postalCode) 
{ 
    this.postalCode = postalCode; 
} 

@Basic 
@Column(name = "miejscowosc", nullable = true, length = 30) 
public String getCity() 
{ 
    return city; 
} 

public void setCity(String city) 
{ 
    this.city = city; 
} 

@Enumerated(EnumType.STRING) 
@Column(name = "sposob_zaplaty", nullable = false, length = 7) 
public PaymentMethod getPaymentMethod() 
{ 
    return paymentMethod; 
} 

public void setPaymentMethod(PaymentMethod paymentMethod) 
{ 
    this.paymentMethod = paymentMethod; 
} 

@Basic 
@Column(name = "uwzglednij_numer_faktury", nullable = false) 
public byte getIncludeInvoiceNum() 
{ 
    return includeInvoiceNum; 
} 

public void setIncludeInvoiceNum(byte includeInvoiceNum) 
{ 
    this.includeInvoiceNum = includeInvoiceNum; 
} 

@Basic 
@Column(name = "alias", nullable = false, length = 30) 
public String getAlias() 
{ 
    return alias; 
} 

public void setAlias(String alias) 
{ 
    this.alias = alias; 
} 

@OneToMany(mappedBy = "contractorMapping") 
public Collection<ServicesList> getServicesList() 
{ 
    return servicesList; 
} 

public void setServicesList(Collection<ServicesList> servicesList) 
{ 
    this.servicesList = servicesList; 
} 
} 

ServicesList

@Entity 
@Table(name = "wykupione_uslugi", schema = "fakturowanie") 
public class ServicesList 
{ 
private int id; 
private int contractorID; 
private int serviceID; 
private Contractor contractorMapping; 
private Service servicesMapping; 

@Id 
@Column(name = "id", nullable = false) 
@GeneratedValue(generator="increment") 
@GenericGenerator(name="increment", strategy = "increment") 
public int getId() 
{ 
    return id; 
} 

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

@Basic 
@Column(name = "kontrahent_id", nullable = false) 
public int getContractorID() { 
    return contractorID; 
} 

public void setContractorID(int contractorID) { 
    this.contractorID = contractorID; 
} 

@Basic 
@Column(name = "usluga_id", nullable = false) 
public int getServiceID() { 
    return serviceID; 
} 

public void setServiceID(int serviceID) { 
    this.serviceID = serviceID; 
} 

@ManyToOne 
@JoinColumn(name = "kontrahent_id", referencedColumnName = "kontrahent_id", insertable = false, updatable = false) 
public Contractor getContractorMapping() { 
    return contractorMapping; 
} 

public void setContractorMapping(Contractor contractorMapping) { 
    this.contractorMapping = contractorMapping; 
} 

@ManyToOne 
@JoinColumn(name = "usluga_id", referencedColumnName = "usluga_id", insertable = false, updatable = false) 
public Service getServicesMapping() { 
    return servicesMapping; 
} 

public void setServicesMapping(Service servicesMapping) { 
    this.servicesMapping = servicesMapping; 
} 
} 

我还创建HibernateUtil类来处理SessionFactory

public class HibernateUtil 
{ 
private static final SessionFactory sessionFactory = buildSessionFactory(); 

private static SessionFactory buildSessionFactory() { 
    try { 
     Configuration configuration = new Configuration(); 
     configuration.configure(); 

     StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder() 
       .configure() 
       .build(); 

     return configuration.buildSessionFactory(standardRegistry); 
    } 
    catch(Exception e) { 
     throw new ExceptionInInitializerError(e); 
    } 
} 

public static Session getSession() 
{ 
    return sessionFactory.openSession(); 
} 

public static void close() 
{ 
    sessionFactory.close(); 
} 
} 

而且Main类看起来是这样的:

public class Main 
{ 
public static void main(String[] args) 
{ 
    Session session = HibernateUtil.getSession(); 
    session.beginTransaction(); 

    List<Service> services = session.createQuery(
      "select Service.serviceName, Service.symbol, Service.unit, Service.unitPrice, Service.tax " + 
        "from ServicesList " + 
        "left join ServicesList.contractorMapping left join ServicesList.servicesMapping " + 
        "where Contractor.alias = 'test'").list(); 

    for(Service s : services) 
    { 
     System.out.println(s.getServiceID() + "\t" + s.getServiceName() + "\t" + s.getSymbol() + "\t" + s.getUnit() + 
       "\t" + s.getUnitPrice() + "\t" + s.getTax()); 
    } 

    session.getTransaction().commit(); 
    session.close(); 
} 
} 

但错误说,有毛病了查询,我真的不知道有什么可以是错误的

Exception in thread "main" java.lang.NullPointerException 
at java.lang.String$CaseInsensitiveComparator.compare(String.java:1192) 
at java.lang.String$CaseInsensitiveComparator.compare(String.java:1186) 
at java.util.TreeMap.getEntryUsingComparator(TreeMap.java:376) 
at java.util.TreeMap.getEntry(TreeMap.java:345) 
at java.util.TreeMap.get(TreeMap.java:278) 
at org.hibernate.dialect.function.SQLFunctionRegistry.findSQLFunction(SQLFunctionRegistry.java:45) 
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.findSQLFunction(SessionFactoryHelper.java:369) 
at org.hibernate.hql.internal.ast.tree.IdentNode.getDataType(IdentNode.java:374) 
at org.hibernate.hql.internal.ast.HqlSqlWalker.lookupProperty(HqlSqlWalker.java:652) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.propertyRef(HqlSqlBaseWalker.java:1140) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3838) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3701) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3579) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:718) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:574) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:311) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:259) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:261) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141) 
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) 
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77) 
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153) 
at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:545) 
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:654) 
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:102) 
at Main.main(Main.java:12) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) 

编辑
被马切伊·科瓦尔斯基 回答帮助,但我依然得到了一些奇怪和不需要的输出,顺便说一句主不会退出(它应该),但是'挂'。我highlited黄色正确的输出。 enter image description here

回答

2

有几件事情在这里..

首先,你正试图使投影(如果你想返回的数据工作,这是一件好事,但不能更新)和期待获得一个实体列表。不这样工作。

第二个,您是以错误的方式引用列。标准是使用一个别名并从那里继续(很容易阅读和维护)。

因此,有那些意思,我不愿意:

1)创建用于投影的特殊结果类,这样它会更容易与查询工作。它也将节省您吨锅炉板代码解析:

package com.mypkg;  

public class ServiceResult{ 

    private String serviceName; 
    private String symbol; 
    private String unit; 
    private BigDecimal unitPrice; 
    private int tax; 

    public ServiceResult(String serviceName, String symbol 
     ,String unit, BigDecimal unitPrice, int tax){ 
     // set the field values 
    } 

} 

2)查询更改为以下:

List<ServiceResult> services = session.createQuery(
    "select new com.mypkg.ServiceResult(service.serviceName 
       ,service.symbol, service.unit 
       , service.unitPrice, service.tax) " + 
    "from ServicesList serviceList" + 
    " left join serviceList.contractorMapping contractor" + 
    " left join serviceList.servicesMapping service" + 
    "where contractor.alias = 'test'") 
    .list(); 

3)如果你的目的是要真正得到全服务实体,然后使用此查询:

List<Service> services = session.createQuery(
    "select service " + 
    "from Service service" + 
    " left join service.servicesLists servicesLists" + 
    " left join servicesLists.contractorMapping contractor" + 
    "where contractor.alias = 'test'") 
    .list(); 

在侧面

由于这里有几个连接,所以您可能需要添加不同的以获得多余的结果。

+0

老实说,如果说到映射我写它基于由IntelliJ生成的一个 – Colonder

+0

我用你的1)和2),它有点作品,但我仍然得到一些不需要的输出,请参阅编辑 – Colonder

+0

看起来不错..在Java中你可以检索ServiceResult对象? –