如何让 Statement.getGeneratedKeys 工作

Posted

技术标签:

【中文标题】如何让 Statement.getGeneratedKeys 工作【英文标题】:How to get Statement.getGeneratedKeys working 【发布时间】:2014-06-06 13:19:19 【问题描述】:

java.sql.Statement的方法getGeneratedKeys()有问题

首先是我的代码:

create.sql: (HSQLDB)

create table Ticket (
    ticketID  INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    persID INTEGER NOT NULL REFERENCES Mitarbeiter(persID),
    zeitpunkt TIMESTAMP(0) NOT NULL,
    betreff VARCHAR(100) NOT NULL,
    text VARCHAR(1000) NOT NULL,
    wichtig BOOLEAN NOT NULL,
    istGeloest BOOLEAN NOT NULL
);

DAO 的创建方法:

@Override
public Ticket create(Ticket t) throws PersistenceException 
    if( t == null ) 
        log.error("PersistenceTicket.create(Ticket t) wurde ein null parameter übergeben");
        throw new PersistenceException("TicketParameter ist null");
    
    PreparedStatement pst = null;

    try 
        pst = con.prepareStatement("INSERT INTO ticket(persID, zeitpunkt, betreff, text, wichtig, istGeloest) VALUES (?,?,?,?,?,?)");

        pst.setInt(1, t.getPersID());
        pst.setTimestamp(2, t.getZeitpunkt());
        pst.setString(3, t.getBetreff());
        pst.setString(4, t.getText());
        pst.setBoolean(5, t.isWichtig());
        pst.setBoolean(6, t.istGeloest());

        int result = pst.executeUpdate();
        if( result > 1 ) 
            return null;
        

        ResultSet rs = pst.getGeneratedKeys();
        if( rs.next() ) 
            t.setTicketID(rs.getInt(1));
        
        else 
            log.debug("No keys generated");
        
        log.info("Ticket mit Betreff " + t.getBetreff() + " in die Datenbank gespeichert" );

        pst.close();
     catch (SQLException e) 
        log.error("Error beim create: " + e.getMessage());
    
    return t;

然后我有一个单元测试来测试生成的密钥:

@Test
public void specialCreateTest() throws PersistenceException 
    Ticket a = this.persT.create(this.testTicket);
    Ticket b = this.persT.create(this.testTicket);
    log.debug(a.getTicketID() +  " < " +  b.getTicketID());
    assertTrue(a.getTicketID() < b.getTicketID());

当我运行测试时,我得到一个失败和以下日志:

DEBUG at.ac.tuwien.sepm.persistence.PersistenceTicketImpl  - No keys generated
DEBUG at.ac.tuwien.sepm.persistence.PersistenceTicketImpl  - No keys generated
DEBUG at.ac.tuwien.sepm.unittests.APersistenceTicketTest  - 0 < 0

所以问题在于.getGeneratedKeys() method returns an empty set, otherwise we wouldnt 看到日志帽子没有生成密钥

【问题讨论】:

【参考方案1】:

改变

pst = con.prepareStatement("INSERT INTO ticket(persID, zeitpunkt, betreff, text, wichtig, istGeloest) VALUES (?,?,?,?,?,?)");

pst = con.prepareStatement("INSERT INTO ticket(persID, zeitpunkt, betreff, text, wichtig, istGeloest) VALUES (?,?,?,?,?,?)", 
        Statement.RETURN_GENERATED_KEYS);

否则PreparedStatement 不会返回密钥。

【讨论】:

以上是关于如何让 Statement.getGeneratedKeys 工作的主要内容,如果未能解决你的问题,请参考以下文章

Jfreechart柱状图如何让变成纯色

android中如何让文字环绕图片

如何让GridView 标题居中

请教如何让UIActivityIndicatorView永远居中

如何让ActionBar标题居中

EBS如何让从值集不显示