Sorry for the awkward title, There isn't an easy way to summarize my problem.
I have 2 related entities:
the real data has been modified to protect sensitive IP, but the problem is the same. so try not to be distracted by the fields not making complete sense.
# 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
has a @ManyToOne
relationship with Item
. Permission
links to Item
via the logic in SQL below:
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
;
As you can see, the join is rather complex, And so far my attempts to wrangle with Hibernate's API have been fruitless. Be aware that these are highly depended on legacy tables that cannot afford a schema change, so that's out of the question.
I've tried to use the @JoinColumnsOrFormulas
annotation and related:
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;
}
but I get the complaint:
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...
Am I expecting too much of the ORM and should I split up the query into more manageable and feasible parts or is this possible using hibernate?