Java 与 sql 服务器的持久性 - 无法插入行,但它与 mysql 一起运行良好,为什么?抱怨 table 已经存在

Java persistence with sql server - cannot insert a row but it works well with mysql, why? Complains that table already exists

这是我的代码:

package sqlserver;

import it.bsec.target.entity.Colore;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Test1 {

    public static void main(String[] args) {
        try {
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        } catch (ClassNotFoundException e1) {
            System.out.println("Failed to register the driver.");
        }

        String connectionUrl = "jdbc:sqlserver://localhost:3306;" +
                   "databaseName=target;integratedSecurity=true;encrypt=true;trustServerCertificate=true;";
        try {
            Connection con = DriverManager.getConnection(connectionUrl);
            Statement stmt = con.createStatement();
            String s = "use target";
            String sql = "SELECT * FROM dbo.Colori";
            ResultSet rs = stmt.executeQuery(sql);
            while(rs.next()) {
                int id  = rs.getInt("Id");
                String desc = rs.getString("Descrizione");
                System.out.println(id + " : " + desc);
            }

            System.setProperty("eclipselink.target-database", "SqlServer");
            System.setProperty("javax.persistence.jdbc.driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
            System.setProperty("javax.persistence.jdbc.url", System.getProperty("jdbc.url", "jdbc:sqlserver://localhost:3306;databaseName=target;integratedSecurity=true;encrypt=true;trustServerCertificate=true;"));
            EntityManagerFactory factory = Persistence.createEntityManagerFactory("TARGET", System.getProperties());
            EntityManager entityManager = factory.createEntityManager();

            Colore c = new Colore();
            c.setId(6);
            c.setDescrizione("WHITE");
            entityManager.persist(c);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

此查询导致将新行插入到 MySQL 中的 table Colori 中。当我使用 SQL 服务器从 Eclipse 中 运行 这个例子时,这是我得到的(并且插入失败):

1 : BLUE
2 : GREY
3 : GREEN
4 : RED
5 : YELLOW
[EL Warning]: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.1.2.v20101206-r8635): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.microsoft.sqlserver.jdbc.SQLServerException: There is already an object named 'Colori' in the database.
Error Code: 2714
Call: CREATE TABLE dbo.Colori (Id INTEGER NOT NULL, Descrizione VARCHAR(255) NULL, PRIMARY KEY (Id))
Query: DataModifyQuery(sql="CREATE TABLE dbo.Colori (Id INTEGER NOT NULL, Descrizione VARCHAR(255) NULL, PRIMARY KEY (Id))")

但是像这样稍微修改这段代码就足够了:

package sqlserver;

import it.bsec.target.entity.Colore;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Test1 {

    public static void main(String[] args) {
        try {
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        } catch (ClassNotFoundException e1) {
            System.out.println("Failed to register the driver.");
        }

        String connectionUrl = "jdbc:sqlserver://localhost:3306;" +
                   "databaseName=target;integratedSecurity=true;encrypt=true;trustServerCertificate=true;";
        try {
            Connection con = DriverManager.getConnection(connectionUrl);
            Statement stmt = con.createStatement();
            String s = "use target";
            String sql = "SELECT * FROM dbo.Colori";
            ResultSet rs = stmt.executeQuery(sql);
            while(rs.next()) {
                int id  = rs.getInt("Id");
                String desc = rs.getString("Descrizione");
                System.out.println(id + " : " + desc);
            }

            System.setProperty("eclipselink.target-database", "SqlServer");
            System.setProperty("javax.persistence.jdbc.driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
            System.setProperty("javax.persistence.jdbc.url", System.getProperty("jdbc.url", "jdbc:sqlserver://localhost:3306;databaseName=target;integratedSecurity=true;encrypt=true;trustServerCertificate=true;"));
            EntityManagerFactory factory = Persistence.createEntityManagerFactory("TARGET", System.getProperties());
            EntityManager entityManager = factory.createEntityManager();
            entityManager.getTransaction().begin();
            entityManager.createNativeQuery("insert into dbo.Colori(Id, Descrizione) values ('6', 'WHITE')").executeUpdate();
            entityManager.getTransaction().commit();
            entityManager.persist(c);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

这是我仍然遇到的错误:

1 : BLUE
2 : GREY
3 : GREEN
4 : RED
5 : YELLOW
[EL Warning]: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.1.2.v20101206-r8635): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.microsoft.sqlserver.jdbc.SQLServerException: There is already an object named 'Colori' in the database.
Error Code: 2714
Call: CREATE TABLE dbo.Colori (Id INTEGER NOT NULL, Descrizione VARCHAR(255) NULL, PRIMARY KEY (Id))
Query: DataModifyQuery(sql="CREATE TABLE dbo.Colori (Id INTEGER NOT NULL, Descrizione VARCHAR(255) NULL, PRIMARY KEY (Id))")

但是,这次插入成功了(尽管有错误)!有谁知道为什么会这样,我做错了什么?特别是,为什么我会收到错误消息,基本上说 table 存在?它当然存在,应该存在,不是吗?我还能如何尝试将任何内容插入不存在的 table?这怎么会是一个错误?

我正在使用 slqjdbc4 驱动程序,eclipse link,java 6 EE 持久性框架及以下,我包括我的实体 Bean 的代码:

package it.bsec.target.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="dbo.Colori")
@SuppressWarnings("serial")
public class Colore implements Serializable {

    @Id
    @Column(name = "Id")
    private Integer id;

    @Column(name = "Descrizione", length = 255)
    private String descrizione;

    public Integer getId() {
        return id;
    }

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

    public String getDescrizione() {
        return descrizione;
    }

    public void setDescrizione(String descrizione) {
        this.descrizione = descrizione;
    }

}

只是SQL服务器与java持久性框架不兼容吗?我知道这听起来很奇怪,但还有什么原因呢?抱歉,但我显然不知道出了什么问题。不用说,当从 SQL Server Management Studio 中执行时,上述查询工作完美。


编辑: 正如 Jens 所建议的那样,我添加了 属性 eclipselink.ddl-generation 并将其值设置为 update,easy fix - 现在它确实适用于本机查询,但是当尝试一个我尝试坚持的例子时实体 Bean,它仍然失败(这次没有错误!)但是它没有向 table 添加任何新行。任何人都知道我还缺少什么,在哪里可以找到这类事情的良好信息来源,我可以从中学习? 谢谢。

这将由JPA 完成。尝试添加 属性 eclipselink.ddl-generation 并将值设置为 update

      System.setProperty("eclipselink.ddl-generation", "update");