Извините за неуклюжий заголовок. Нет простого способа подвести итог моей проблемы.
У меня есть 2 связанных объекта:
реальнаяДанные были изменены для защиты конфиденциальных IP, но проблема та же.поэтому старайтесь не отвлекаться на поля, не имеющие полного смысла.
# Permission
+----------------+--------------+
| Column | type |
+----------------+--------------+
| perm_id | Number(20,0) |
| item_id1_id2 | VARCHAR2(8) |
| date_code | VARCHAR2(6) |
+----------------+--------------+
# Item
+-----------------+-------------+
| Column | type |
+-----------------+-------------+
| id1 | VARCHAR2(4) |
| id2 | VARCHAR2(4) |
| date_code | VARCHAR2(6) |
| some_data_field | VARCHAR(20) |
+-----------------+-------------+
Permission
имеет отношение @ManyToOne
с Item
.Permission
ссылки на Item
через логику в SQL ниже:
SELECT p.*, i.*
FROM Permission p
JOIN (
SELECT
id1 || id2 as joined_ids, -- the p.item_id1_id2 is 2 CONCATed columns to Item.id1 and Item.id2
effective_date_code, -- this column specifies WHEN this data is effective by, i.e. all date codes for permissions between this date and not including the next greatest date should link to this record.
some_data_field, -- and arbitrary data point that gives this object its usefulness.
rank() over (partition by id1, id2 order by effective_date_code DESC) max_date_code -- this essentially gives us the
FROM Item
-- where effective_date_code <= p.date_code
ORDER BY max_date_code
) i
ON i.max_date_code = 1
and p.item_id1_id2 = i.joined_ids
;
Как видите, соединение довольно сложное, и до сих пормои попытки спорить с API Hibernate были безрезультатными.Имейте в виду, что они сильно зависят от устаревших таблиц, которые не могут позволить себе изменение схемы, поэтому об этом не может быть и речи.
Я пытался использовать аннотацию @JoinColumnsOrFormulas
и относился к ней:
public class Permission {
// ...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumnsOrFormulas(value = {
@JoinColumnOrFormula(formula = @JoinFormula(value = "item_id1_id2", referencedColumnName = "id1 || id2")),
@JoinColumnOrFormula(column = @JoinColumn(name = "date_code", referencedColumnName = "effective_date_code")) // This isn't the final thing, but just for testing purposes I'm linking like this.
})
public Subject subject;
}
но я получаю жалобу:
java.lang.RuntimeException: org.hibernate.AnnotationException: A Foreign key
\ refering com.example.Item from com.example.Permission has the wrong number
\ of column. should be 3...
Ожидаю ли я слишком много от ORM и должен ли я разделить запрос на более управляемые и выполнимые части или это возможно с помощью hibernate?