【问题标题】:J2EE JPA and class inheritance - Unknown column 'field list'J2EE JPA 和类继承 - 未知列“字段列表”
【发布时间】:2015-06-08 21:58:01
【问题描述】:

嗨,我对我一直在努力解决的一个问题有点绝望。作为一种实践,我正在尝试构建非常简单的电子银行应用程序。所以一个表称为 products (str productName, str descr),另一个是 SavingAccounts(int accountNo, int clientNo, int balance)。我有两个班级:

savingsAccount.java

@Entity
@Table(name = "savingsAccounts")  
@NamedQueries({  
@NamedQuery(name = "savingsAccount.findAll", query = "SELECT s FROM savingsAccount s"),
@NamedQuery(name = "savingsAccount.findByClientNo", query = "SELECT s FROM savingsAccount s WHERE s.clientNo = :p_clientNo")
})

public class savingsAccount extends product implements Serializable {
@Id
@Basic(optional = false)
@NotNull  
@Column(name = "accountNo")  
private Integer accountNo;  
@Basic(optional = false)  
@NotNull  
@Column(name = "clientNo")  
private Integer clientNo;  
@Basic(optional = false)  
@NotNull  
@Column(name = "balance")  
private double balance;

//getters and setters nad constructorscode here

product.java

@Entity  
@Table(name = "products")  
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)  
public class product implements Serializable {
@Id  
@Basic(optional = false)  
@NotNull  
@Size(min = 1, max = 20)  
@Column(name = "productName")  
public String productName;  

@Basic(optional = false)
@NotNull
@Size(min = 1, max = 100)
@Column(name = "descr")
private String descr;

//gettes、setter和constructor

但是当我运行 namedquery SavingAccount.findByClientNo 时,它给了我这个语句:

SELECT accountNo, productName, balance, clientNo, descr FROM savingsAccounts WHERE (clientNo = ?)

它给了我这个错误: 内部异常:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'descr' in 'field list'

我不知何故“觉得”问题在于 SavingAccount 表中没有名为 descr 的字段,但我真的不知道如何使其工作......感谢大家的帮助。

【问题讨论】:

  • 感谢人们提供非常有用的提示。也许我会尝试解释我这样做的动机。也许你会告诉我这是完全错误的:)。原因是让它灵活 - 例如。当产品描述发生变化时,数据库表中的一个简单更新就可以完成整个工作,并且只要所有储蓄账户都有相同的描述,我就尝试扩展类产品。
  • 第二个原因是显示 - 所有需要显示的信息都应该包含在同一个类中 - 例如产品概览将在一行中显示有关余额、accountNo、clientNo 和所需字段描述的信息。也许真的有一些更优雅的方式...... :)

标签: java jakarta-ee jpa inheritance


【解决方案1】:

您的类savingsAccount 扩展了product,因此它继承了该类的字段。因此在对应的表savingsAccounts 中也应该有descrproductName 的列。

做一个alter table savingsAccounts add column descr varchar(255)或类似的,另一个productName,它应该可以工作。

哦,我不能不说:类名应该以大写开头,比如Product

【讨论】:

    【解决方案2】:

    关于你的问题:

    为什么要在“SavingsAccount”上扩展“产品”?如果您确定需要这些,那么正如 geert3 所说,您缺少“SavingAccounts”表中的相应列。


    还不能发布cmets,抱歉不相关的部分,但仍有一些反馈:

    你为什么使用@Basic 注释?在这里似乎没有用。

    我没有看到您的继承策略的优势,但是 JEE6 的 Oracle 教程说了很多关于 TABLE_PER_CLASS 的内容。 http://docs.oracle.com/javaee/6/tutorial/doc/bnbqn.html

    根据您的需要,您还可以考虑从命名查询注释切换到存储库接口,它提供由 JPA 自动解析的基本查询,并将您的域模型与您的查询分开。

    http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#_declaring_interfaces

    您似乎配置实体的方式,您可能无法充分利用它。例如,如果你的 clientNo 指的是一个 Client 表/实体,那么你可以有类似

    @OneToOne(fetch = FetchType.LAZY) //To adapt with the right relationship between savingsAccount/client 
    @JoinColumn(name="clientNo")
    private Client client;
    

    【讨论】:

      【解决方案3】:

      所以,如果您使用的是TABLE_PER_CLASS,那么您应该有 2 个包含以下列的数据库表:

      产品

      • productName(主键)
      • 描述

      储蓄账户

      • productName(继承自 products)
      • descr(继承自产品)
      • 帐号
      • 客户号
      • 余额

      但是,我认为这不是您想要的,是吗?我认为您通过让 SavingAccounts 从产品继承来混淆问题。如果您在这种情况下不需要继承,那么我不会使用它。

      顺便说一句,您在实体中使用了非常冗长的列定义。

      代替:

      @Basic(optional = false)
      @NotNull
      @Size(min = 1, max = 100)
      @Column(name = "descr")
      private String descr;
      

      你可以写:

      @Column(name = "descr", length = 100, nullable = false)
      private String descr;
      

      实际上,如果数据库列名与你的Entity字段名完全匹配,你甚至不需要name = ...,因此:

      @Column(length = 100, nullable = false)
      private String descr;
      

      @Basic 假定用于基本数据类型(StringIntegerCharacter 等)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多