Неверное имя объекта 'ACCOUNT_orders'?Spring-MVC Hibernate с вопросом аннотации - PullRequest
1 голос
/ 26 марта 2011

Я новичок в Hibernate. У меня есть таблица заказов и счетов в БД,

CREATE TABLE [dbo].[ORDERS](
    [PRICE] [decimal](12, 2) NULL,
    [ORDERID] [int] IDENTITY(0,1) NOT NULL,
    [ACCOUNT_ACCOUNTID] [int] NULL,
 CONSTRAINT [PK_ORDER] PRIMARY KEY CLUSTERED 
(
    [ORDERID] ASC
)WITH (  STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF )  
)  

Таблица счетов:

CREATE TABLE [dbo].[ACCOUNT](
    [BALANCE] [decimal](12, 2) NULL,
    [ACCOUNTID] [int] IDENTITY(0,1) NOT NULL,
    [PROFILE_USERID] [varchar](250) NULL,
 CONSTRAINT [PK_ACCOUNT] PRIMARY KEY CLUSTERED 
(
    [ACCOUNTID] ASC
)WITH (  STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF )  
)

Я пытаюсь сделать так, чтобы на одном аккаунте было много заказов. У меня есть следующие классы:

@Table(name="ACCOUNT")
public class Account implements Serializable, IEntity{

    private static final long serialVersionUID = 1L;
    private int accountID;
    private double balance;
    private List<Order> orders; 

    @Id
    @GeneratedValue
    public int getAccountID() {
        return accountID;
    }
public void setAccountID(int accountID) {
    this.accountID = accountID;
}

public double getBalance() {
    return balance;
}
public void setBalance(double balance) {
    this.balance = balance;
}

@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinColumn(name = "ACCOUNT_ACCOUNTID",nullable=false,insertable=true,updatable=true)
public List<Order> getOrders()
{
    return orders;
}  
public void setOrders(List<Order> orders)
    {
        this.orders = orders;
    }       
}

Класс заказа:

@Table(name="ORDERS")
public class Order implements Serializable, IEntity
{
    private int orderID;
    private double price;
    @Column(name="ACCOUNT_ACCOUNTID")
    private Account account; 

    @Id
    @GeneratedValue
    public int getOrderID() {
    return orderID;
}
public void setOrderID(int orderID) {
    this.orderID = orderID;
}
public double getPrice() {
    return price;
}
public void setPrice(double price) {
    this.price = price;
}

@ManyToOne(cascade = CascadeType.ALL ,fetch = FetchType.EAGER)
public Account getAccount() {
        return account;
    }
    public void setAccount(Account account) {
        this.account = account;
    }  
}

Но когда я пытаюсь получить доступ к методу List HibernateTemplate со следующим HQL:

SQL_QUERY =" from Account as a where a.balance='"+bal+"'";

Это дает мне следующее выражение:

(JDBCExceptionReporter.java:72) - Invalid object name 'ACCOUNT_orders'.

java.lang.NullPointerException
    at com.microsoft.trade.service.TradeServiceImplementor.loginVerify(TradeServiceImplementor.java:59)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

Помогите мне, пожалуйста. Заранее спасибо.

1 Ответ

2 голосов
/ 26 марта 2011

У вас есть двунаправленная ассоциация OneToMany: на счету много заказов, а на заказ есть одна учетная запись. Одна из ассоциаций является обратной к другой. Таким образом, вы должны определить отображение для этой ассоциации на одной стороне (обычно на стороне многих: это предписано JPA) и объявить, что ассоциация обратна другой на другой стороне (одной стороне):

@Entity
public class Account implements Serializable, IEntity{
    // ...
    private List<Order> orders; 

    // mappedBy is used to indicate that this association is the inverse of the association
    // mapped by the account property of the Order entity
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy="account")
    public List<Order> getOrders() {
        return orders;
    }       
}

@Entity
public class Order implements Serializable, IEntity {
    // ...
    // a relationship to another entity is never mapped by @Column. You can't have annotations 
    // on the field and the getter. Choose one or the other, and be consistent for all 
    // the properties of the entity
    private Account account; 

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "ACCOUNT_ACCOUNTID")
    public Account getAccount() {
        return account;
    }  
}

Обратите внимание, что большую часть времени неправильно иметь каскад на всех сторонах отношений. Вы не хотите, чтобы аккаунт был удален при заказе, не так ли? На счетах хранятся заказы, а не наоборот.

Наконец, в отношении вашего запроса: это не SQL-запрос, а HQL-запрос. И вам не следует использовать конкатенацию, а связывать параметры: это безопаснее (без атаки с использованием инъекций), более четко (без необходимости цитирования, более читабельно) и быстрее:

String hql = "from Account a where a.balance = :theBalance";
Query query = session.createQuery();
query.setParameter("theBalance", new BigDecimal("12.5");
...