java.sql.SQLException:表/视图'LOCATION'已存在于Schema'APP'中

时间:2016-02-26 22:50:48

标签: java sql spring rest derby

我正在JBOSS EAP 6.2中开发和部署RESTful服务。对于此任务,我使用CXF,Spring和Embedded Derby进行数据存储。 我花了几个小时尝试调试此错误但无法实现。我已经多次检查过数据库是完全空的并且没有任何表。但我总是收到相同的堆栈跟踪。 我也读过类似的问题,但这也没有帮助。 所以,这是代码:

资源类

package eu.pedu.adv16s._4_1800.macv03_macura.logika;

import eu.pedu.adv16s_fw.game_txt.IBag;
import eu.pedu.adv16s_fw.game_txt.IItem;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;


/**
 * Třída Inventar - představuje inventář pro sbírané věci.
 * Kapacita je omezena na dvě věci.
 *
 * @author    Viktor Mačura
 * @version   semestrální práce 4IT101 ZS 2015/2016
 */
public class Inventar implements IBag
{
    private Map<String, Vec> seznamVeci;
    static final int kapacita = 2;

/**
 * Vytvoření inventáře, věci se ukládají do seznamu 
 * pomocí HashMap
 */
public Inventar()
{
    seznamVeci = new HashMap<>();



/**
 * Vkládá věci do inventáře.
 * @param Vec vkládáná věc
 * @return boolean true pokud je v inventáři místo,
 * false pokud v něm není místo
 */
public boolean vlozVec(Vec vec)
{
    if (seznamVeci.size() < kapacita) 
    {
        seznamVeci.put(vec.getNazev(), vec);
        return true;
    }
    return false;
}

/**
 * Odebírá věc z inventáře.
 * @param String název věci
 * @return Vec pokud je věc v inventáři, odebere ji a vrátí na ni odkaz,
 * pokud neni, vrátí null
 */
public Vec seberVec(String nazev)
{
    Vec odebirana = null;
    if (seznamVeci.containsKey(nazev)) 
    {
        odebirana = seznamVeci.get(nazev);
        seznamVeci.remove(nazev);
    }
    return odebirana;
}

/**
 * Zjišťuje, jestli je požadovaná věc v inventáři.
 * @param String název věci
 * @return boolean true pokud je v inventáři, false pokud není v inventáři.
 */
public boolean obsahujeVec(String nazev) 
{
    return seznamVeci.containsKey(nazev);
}

/**
 * Vrací odkaz na požadovanou věc.
 * @param String název věci
 * @return Vec
 */
public Vec getVec(String nazev) 
{
    return seznamVeci.get(nazev);
}

@Override
public int getCapacity() 
{
    return kapacita;
}

@Override
public Collection<Vec> getItems() 
{
    return seznamVeci.values();

}
}

DAO课程

package rest_3;

import java.sql.SQLException;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

@Path("/dataservice")
@Produces({"application/xml", "application/json"})
@Consumes({"application/xml", "application/json"})
public class DataService {

    private ApplicationContext context = new ClassPathXmlApplicationContext("rest_3/servicebean.xml");
    private DAO dao = (DAO) context.getBean("daoBean");

    public DataService(DAO dao) {

    }

    @GET
    @Path("/location/{id}")
    public Location getLocation(@PathParam("id") int id) throws SQLException {
        Location loc = dao.getLocation(id);
        if (loc == null) {
            ResponseBuilder builder = Response.status(Status.BAD_REQUEST);
            builder.type("application/xml");
            builder.entity("<error>Location Not Found</error>");
            throw new WebApplicationException(builder.build());
        } 
        return loc;
    }

    @POST
    @Path("/location")
    public Response addLocation(Location loc) throws SQLException {
        if(loc == null)
            return Response.status(Status.BAD_REQUEST).build();
        dao.addLocation(loc);
        return Response.ok().build();
    }

    @DELETE
    @Path("/location/{id}")
    public Response deleteLocation(@PathParam("id") int id) throws SQLException {
        Location loc = dao.getLocation(id);
        if(loc == null) 
            return Response.status(Status.BAD_REQUEST).build();
        dao.deleteLocation(id);
        return Response.ok().build();

    }

    @PUT
    @Path("/location")
    public Response updateLocation(Location loc) throws SQLException {
        if(dao.getLocation(loc.getId()) == null)
            return Response.status(Status.BAD_REQUEST).build();
        dao.updateLocation(loc);
        return Response.ok().build();
    }

    @DELETE
    @Path("/location")
    public void dropTable() throws SQLException {
        dao.dropTable();
    }


}

服务和DAO bean。

package rest_3;


import java.sql.*;

import org.apache.derby.jdbc.EmbeddedDataSource;

public class DAO {

    private static Connection conn;
    private static Statement statement;
    private static PreparedStatement prep;

    public DAO() throws SQLException {
        this.load();
    }

    public void load() throws SQLException {

        EmbeddedDataSource ds = new EmbeddedDataSource(); 
        ds.setDatabaseName("derbyDB");
        ds.setCreateDatabase("create");
        conn = ds.getConnection();
        statement = conn.createStatement();
        statement.execute("create table location(id int, country varchar(40))");
        statement.execute("insert into location values(1, 'MEXICO')");
        statement.execute("insert into location values(2, 'SPAIN')");
        statement.execute("insert into location values(3, 'UK')");
        statement.execute("insert into location values(4, 'ITALY')");
        statement.execute("insert into location values(5, 'JAPAN')");

    }


    public Location getLocation(int id) throws SQLException {
        ResultSet rs = statement.executeQuery("select from location where id = "  + id);
        rs.next();
        return new Location(rs.getInt("id"), rs.getString("country"));
    }

    public void addLocation(Location loc) throws SQLException{
        int id = loc.getId();
        String country = loc.getCountry();
        prep = conn.prepareStatement("insert into location values(?,?)");
        prep.setInt(1, id);
        prep.setString(2, country);
        prep.execute();
    }

    public void deleteLocation(int id) throws SQLException{
        statement = conn.createStatement();
        statement.executeUpdate("delete from location where id = " + id);

    }

    public void updateLocation(Location loc) throws SQLException {
        int id = loc.getId();
        String country = loc.getCountry();
        statement = conn.createStatement();
        statement.execute("update location set country = " + country + " where id = " + id);
    }

    public void dropTable() throws SQLException {
        statement = conn.createStatement();
        statement.execute("drop table location");
    }

}

服务bean配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<bean id="dataService" class="rest_3.DataService">
    <constructor-arg ref ="daoBean"/>
</bean>

<bean id="daoBean" class="rest_3.DAO">
</bean>

</beans>

的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jaxrs="http://cxf.apache.org/jaxrs"
  xmlns:cxf="http://cxf.apache.org/core"
  xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
  <import resource="classpath:META-INF/cxf/cxf.xml" />
  <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
 <jaxrs:server id="DataService" address="/">
    <jaxrs:features>
     <cxf:logging/>
</jaxrs:features>
<jaxrs:serviceBeans>
      <ref bean="dataService" />
    </jaxrs:serviceBeans>
  </jaxrs:server>
</beans>

堆栈追踪:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        WEB-INF/beans.xml
        classpath:rest_3/servicebean.xml
        </param-value>
  </context-param>
  <listener>
    <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
  </listener>
  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>
            org.apache.cxf.transport.servlet.CXFServlet
        </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

2 个答案:

答案 0 :(得分:2)

来自setCreateDatabase()的Javadoc(强调我的):

  

参数:
  create - 如果设置为字符串&#34; create&#34;,此数据源将尝试创建databaseName, 的新数据库,或者如果该名称已存在,则启动数据库

因此,第一次运行代码时,将创建数据库并创建表。第二次没有重新创建数据库,create table失败,因为它已经存在。

在DAO的构造函数中创建数据库和表是非常糟糕的代码味道。如果确实必须这样做,请确保在尝试创建数据库之前删除数据库。如果这不适用于您的设计,那么您刚刚发现为什么在构造函数中创建数据库是个坏主意。

答案 1 :(得分:0)

我刚删除了这一行,现在工作正常。

statement.execute("create table location(id int, country varchar(40))");