2015-08-19 4 views
3

У меня есть таблица с именем printer с 3 полями varchar2, в результате чего создается составной идентификатор, класс Printer.java и класс PrinterID.java (для составного ID).Hibernate SELECT on Composite Key дает непредвиденную ошибку char

@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: unexpected char: '@' [from Printer where id = [email protected]]

Что случилось с "@ 77c95c8b" - Это из Метод PrinterId.hashCode()? Как это исправить?

ответ

1

PrinterId @ 77c95c8b выглядит как результат Object.toString() - который использует значение хэша, как вы подозревали. Итак, первое, что поможет, - @Override tostring() метод PrinterId, чтобы обеспечить хороший вывод (Eclipse и большинство других IDE могут сгенерировать его для вас). Что-то вроде:

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

Однако, я бы не ожидать, Hibernate, чтобы попытаться преобразовать идентификатор в строку при использовании Session.load(), потому что вы переопределить атрибуты и в любом случае он будет параметризировать запрос. Я подозреваю, что вы где-то создает запрос SQL и построение его непосредственно с идентификатором, следовательно, косвенным образом, используя метод ToString, возможно:

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

Этого можно избежать путем параметрирования запроса.

Если вы действительно используете session.load, то, пожалуйста, оставьте мне комментарий.

+0

Я пробовал несколько вещей. Во-первых, я попробовал его, как вы подозревали. Эта неудача делает полный смысл - это не строка. С тех пор я пробовал: PrinterId compId = new PrinterId (a, b, c); Принтер aPrinter = (принтер) session.createQuery ("выбрать из р принтера р, где ID =: комп") \t .setString (": комп", БМНПР) \t .setString (": б", б) \t .setString (": c", c) \t .uniqueResult(); Также: Принтер aPrinter = (Принтер) session.createQuery ("выберите p из принтера p, где A =: a и B =: b и C =: c") \t .setString (": a", a) \t .setString (": b", b) \t .setString (": c", c) \t .uniqueResult(); Все они дают ту же ошибку. –

+0

Как насчет session.get (Printer.class, id)? Вам не нужно создавать свой собственный запрос, чтобы получить один экземпляр по id – drrob

+0

Я нашел ошибку. Я немного смущен, чтобы сказать, но ты на месте. Функция get() работает нормально. Был следующий вызов, который был встроен, когда метод toString() автоматически вызывался. Спасибо, что указал мне на это. –