【问题标题】:Hibernate SELECT on Composite Key gives unexpected char error复合键上的休眠 SELECT 给出了意外的字符错误
【发布时间】:2015-08-19 00:45:54
【问题描述】:

我有一个名为 printer 的表,其中包含 3 个 varchar2 字段,这些字段构成一个复合 ID、一个 Printer.java 类和一个 PrinterID.java 类(用于复合 ID)。

@Entity
public class Printer implements java.io.Serializable {
    @EmbeddedId
    @AttributeOverrides(
        {
            @AttributeOverride(name = "rep", column = @Column(name = "REP", nullable = false, length = 30)),
            @AttributeOverride(name = "quarter", column = @Column(name = "QUARTER", nullable = false, length = 2)),

            @AttributeOverride(name = "product", column = @Column(name = "PRODUCT", nullable = false, length = 20)),
        }
    )
    private PrinterId id;


@Embeddable
public class PrinterId implements java.io.Serializable {
    private String rep;
    private String quarter;
    private String product;

另一个类中的代码...

private Printer getPrinter(String a, String b, String c) {
    Session session = // code to get and open a session
    session.beginTransaction
    PrinterId compId = new PrinterId(a, b, c);
    Printer aPrinter = (Printer) session.load(Printer.class, compId);
    return aPrinter;
}

我收到以下错误:

org.hibernate.QueryException: 意外字符: '@' [来自 Printer where id = PrinterId@77c95c8b]

“@77c95c8b”是怎么回事 - 是来自 PrinterId.hashCode() 方法吗?我该如何解决这个问题?

【问题讨论】:

    标签: java hibernate composite-key


    【解决方案1】:

    PrinterId@77c95c8b 看起来是 Object.toString() 的输出——正如您所怀疑的,它使用哈希值。因此,有帮助的第一件事是@Override PrinterId 的 toString() 方法以提供一个不错的输出(Eclipse 和大多数其他 IDE 可以为您生成它)。比如:

    public String toString() {
        return "PrinterId:" + rep + "," + quarter + "," + product;
    }
    

    但是,我不希望 Hibernate 在您使用 session.load() 时尝试将 id 转换为字符串,因为您已经覆盖了属性并且无论如何它都会参数化查询。我怀疑你在某个地方创建了一个 SQL 查询并直接使用 id 构建它,因此隐式使用 toString 方法,也许:

    "SELECT ... FROM printer WHERE id = " + printerId;
    

    这可以通过参数化查询来避免。

    如果你真的只使用 session.load 那么请给我留言。

    【讨论】:

    • 我已经尝试了几件事。首先,我尝试了内联,就像你怀疑的那样。这种失败是完全有道理的——它不是一个字符串。从那以后我尝试了: PrinterId compId = new PrinterId(a, b, c); Printer aPrinter = (Printer) session.createQuery("select p from Printer p where id = :comp") .setString(":comp", compId) .setString(":b", b) .setString(":c" , c) .uniqueResult();另外: Printer aPrinter = (Printer) session.createQuery("select p from Printer p where A = :a and B = :b and C = :c") .setString(":a", a) .setString(": b", b) .setString(":c", c) .uniqueResult();他们都给出了同样的错误。
    • session.get(Printer.class, id) 怎么样?您不需要创建自己的查询只是为了通过 id 获取单个实例
    • 我发现了错误。我有点不好意思说,但你说得对。 get() 工作正常。随后有一个内联调用,其中自动调用了 toString() 方法。感谢您指点我寻找那个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    相关资源
    最近更新 更多