如何从EJB数据库删除并重建同名表?Derby SQL异常求助
解决EJB数据库表重建及Derby DATE列SQL异常问题
嘿,我来帮你搞定这两个问题——先说说怎么删除旧表并创建同名新表,再解决那个烦人的Derby SQL异常:
一、删除现有表并创建同名新表的实现方式
1. 用JPA自动生成Schema(适合开发环境)
如果你的EJB项目用了JPA(比如Hibernate或者EclipseLink),可以通过配置让框架自动帮你删表重建:
- 对于Hibernate,在
persistence.xml里加这个配置:
启动时会先删除所有旧表,再根据实体类生成新表;关闭应用时还会删掉表,只适合开发测试,生产环境绝对别用,会丢数据!<property name="hibernate.hbm2ddl.auto" value="create-drop" /> - 对于EclipseLink,配置改成:
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
2. 手动执行SQL脚本(更可控)
如果需要在特定业务时机执行操作,或者没用到JPA,可以通过EntityManager或者JDBC手动执行SQL:
用JPA EntityManager的方式:
@Stateless public class TableService { @PersistenceContext private EntityManager em; public void rebuildTable(String tableName) { // 先删表,Derby支持IF EXISTS避免表不存在时报错 em.createNativeQuery("DROP TABLE IF EXISTS " + tableName).executeUpdate(); // 创建新表,这里注意列名别用关键字(后面会说) String createSql = String.format("CREATE TABLE %s (" + "ID INT PRIMARY KEY, " + "EVENT_DATE DATE, " + "CONTENT VARCHAR(255)" + ")", tableName); em.createNativeQuery(createSql).executeUpdate(); } }
用JDBC直接操作的方式:
@Stateless public class TableService { @Resource(lookup = "jdbc/YourEJBDataSource") private DataSource dataSource; public void rebuildTable(String tableName) throws SQLException { try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) { stmt.execute("DROP TABLE IF EXISTS " + tableName); String createSql = String.format("CREATE TABLE %s (" + "ID INT PRIMARY KEY, " + "EVENT_DATE DATE, " + "CONTENT VARCHAR(255)" + ")", tableName); stmt.execute(createSql); } } }
二、解决Column 'DATE' is either not in any table...异常
这个错误的根源很明确:你把DATE当成了列名,但DATE是Derby的SQL保留关键字,数据库会把它当成SQL语法的一部分,而不是表的列名,所以就报错了。有两种解决办法:
1. 重命名列名(强烈推荐)
直接把列名改成非保留字,比如EVENT_DATE、CREATE_DATE,这样从根源避免冲突。比如实体类里的字段:
@Column(name = "EVENT_DATE") private LocalDate eventDate;
对应的建表SQL里也改成EVENT_DATE DATE,这样就不会有语法冲突了。
2. 用引号包裹列名(临时方案)
如果因为特殊原因必须保留DATE作为列名,那就在SQL语句里用双引号把列名包起来,告诉Derby这是一个标识符而不是关键字:
CREATE TABLE YOUR_TABLE_NAME ( ID INT PRIMARY KEY, "DATE" DATE, -- 双引号包裹列名 CONTENT VARCHAR(255) )
对应的JPA实体类也要在@Column里转义双引号:
@Column(name = "\"DATE\"") // Java里需要用转义符处理双引号 private LocalDate date;
不过这种方式不推荐,因为不同数据库的标识符引用规则不一样(比如MySQL用反引号,Oracle用双引号),会降低代码的可移植性。
内容的提问来源于stack exchange,提问作者IT16031180 Fazlan M.F.M.
相关产品推荐
相关产品推荐

