JDBC:在同一事务中创建的 PK 上的外键

发布于 2024-11-09 02:11:16 字数 1672 浏览 0 评论 0原文

我的 MySQL 数据库中有两个表,它们是这样创建的:

CREATE TABLE table1 (
  id int auto_increment,
  name varchar(10),
  primary key(id)
) engine=innodb

and

CREATE TABLE table2 (
  id_fk int,
  stuff varchar(30),
  CONSTRAINT fk_id FOREIGN KEY(id_fk) REFERENCES table1(id) ON DELETE CASCADE
) engine=innodb

(这些不是原始表。重点是 table2 有一个外键引用表 1 中的主键)

现在在我的代码中,我想将条目添加到一个事务中的两个表中。所以我将 autoCommit 设置为 false:

    Connection c = null;        

    PreparedStatement insertTable1 = null;
    PreparedStatement insertTable2 = null;

    try {
        // dataSource was retreived via JNDI
        c = dataSource.getConnection();
        c.setAutoCommit(false);

        // will return the created primary key
        insertTable1 = c.prepareStatement("INSERT INTO table1(name) VALUES(?)",Statement.RETURN_GENERATED_KEYS);
        insertTable2 = c.prepareStatement("INSERT INTO table2 VALUES(?,?)");

        insertTable1.setString(1,"hage");
        int hageId = insertTable1.executeUpdate();

        insertTable2.setInt(1,hageId);
        insertTable2.setString(2,"bla bla bla");
        insertTable2.executeUpdate();

        // commit
        c.commit();
   } catch(SQLException e) {
        c.rollback();
   } finally {
      // close stuff
   }

当我执行上面的代码时,我得到一个异常:

MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails

在我提交之前,主键似乎在事务中不可用。

我在这里错过了什么吗?我真的认为生成的主键应该在事务中可用。

该程序使用 mysql-connector 5.1.14 和 MySQL 5.5.8 在 Glassfish 3.0.1 上运行

非常感谢任何帮助!

问候, 哈格

I have two tables in my MySQL database, which were created like this:

CREATE TABLE table1 (
  id int auto_increment,
  name varchar(10),
  primary key(id)
) engine=innodb

and

CREATE TABLE table2 (
  id_fk int,
  stuff varchar(30),
  CONSTRAINT fk_id FOREIGN KEY(id_fk) REFERENCES table1(id) ON DELETE CASCADE
) engine=innodb

(These are not the original tables. The point is that table2 has a foreign key referencing the primary key in table 1)

Now in my code, I would like to add entries to both of the tables within one transaction. So I set autoCommit to false:

    Connection c = null;        

    PreparedStatement insertTable1 = null;
    PreparedStatement insertTable2 = null;

    try {
        // dataSource was retreived via JNDI
        c = dataSource.getConnection();
        c.setAutoCommit(false);

        // will return the created primary key
        insertTable1 = c.prepareStatement("INSERT INTO table1(name) VALUES(?)",Statement.RETURN_GENERATED_KEYS);
        insertTable2 = c.prepareStatement("INSERT INTO table2 VALUES(?,?)");

        insertTable1.setString(1,"hage");
        int hageId = insertTable1.executeUpdate();

        insertTable2.setInt(1,hageId);
        insertTable2.setString(2,"bla bla bla");
        insertTable2.executeUpdate();

        // commit
        c.commit();
   } catch(SQLException e) {
        c.rollback();
   } finally {
      // close stuff
   }

When I execute the code above, I get an Exception:

MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails

It seems like the primary key is not available in the transaction before I commit.

Am I missing something here? I really think the generated primary key should be available in the transaction.

The program runs on a Glassfish 3.0.1 using mysql-connector 5.1.14 and MySQL 5.5.8

Any help is really appreciated!

Regards,
hage

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

街道布景 2024-11-16 02:11:16

您错过了返回的更新 id 的某些内容,您必须这样做:

Long hageId = null;

try {
    result = insertTable1.executeUpdate();
} catch (Throwable e) {
    ...
}

ResultSet rs = null;

try {
    rs = insertTable1.getGeneratedKeys();
    if (rs.next()) {
        hageId = rs.getLong(1);
    }
 ...

You missed something for the returned updated id , you have to do like this :

Long hageId = null;

try {
    result = insertTable1.executeUpdate();
} catch (Throwable e) {
    ...
}

ResultSet rs = null;

try {
    rs = insertTable1.getGeneratedKeys();
    if (rs.next()) {
        hageId = rs.getLong(1);
    }
 ...
蓝戈者 2024-11-16 02:11:16

不要使用executeUpdate(),而是使用execute(),然后返回主键。

http://www.coderanch.com/t /301594/JDBC/java/Difference- Between-execute-executeQuery-executeUpdate

但我不使用数据库...所以我可能会犯错误

Instead of using executeUpdate() use execute() and then return the primary key.

http://www.coderanch.com/t/301594/JDBC/java/Difference-between-execute-executeQuery-executeUpdate

But I don't work with db...so I could do a mistake

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文