Re: HHH-6221 foreign keys with shared columns
by Jason Pyeron
Has there been any thoughts on this issue?
The mitigation(below email) does not work for a more fringe case discovered today:
Class A
{
@Id
@ManyToOne
B src
@Id
@ManyToOne
B target
String data
}
Class B
{
@Id
@ManyToOne
C c
@Id
Long id
}
create table A
(
b_id_c_1 bigint not null,
b_id_c_2 bigint not null,
b_id_src bigint not null,
b_id_target bigint not null,
data varchar(max) null,
primary key (b_id_c_1, b_id_c_2,b_id_src,b_id_target),
foreign key (b_id_c_1, b_id_c_2,b_id_src) references B(b_id_c_1, b_id_c_2, b_id),
foreign key (b_id_c_1, b_id_c_2,b_id_target) references B(b_id_c_1, b_id_c_2, b_id)
);
Also worth mentioning that the mitigation below requires manual re-setting of the ManyToOne properties after the referenced object is persisted.
From: Jason Pyeron [mailto:jpyeron@pdinc.us]
Sent: Sunday, May 24, 2020 1:09 PM
To: INTERNAL
Subject: RE: HHH-6221 foreign keys with shared columns
@ManyToOne
@JoinColumns
({
@JoinColumn(name = "request_id", referencedColumnName = "request_id", insertable = false, updatable = false),
@JoinColumn(name = "parent", referencedColumnName = "id"/*, insertable = false, updatable = false*/)
})
public Signature getParent()
{
return this.parent;
}
And
public static void checkPropertyConsistency(Ejb3Column[] columns, String propertyName) {
int nbrOfColumns = columns.length;
if ( nbrOfColumns > 1 ) {
for (int currentIndex = 1; currentIndex < nbrOfColumns; currentIndex++) {
if (columns[currentIndex].isFormula() || columns[currentIndex - 1].isFormula()) {
continue;
}
/* if ( columns[currentIndex].isInsertable() != columns[currentIndex - 1].isInsertable() ) {
throw new AnnotationException(
"Mixing insertable and non insertable columns in a property is not allowed: " + propertyName
);
}*/
if ( columns[currentIndex].isNullable() != columns[currentIndex - 1].isNullable() ) {
throw new AnnotationException(
"Mixing nullable and non nullable columns in a property is not allowed: " + propertyName
);
}
/* if ( columns[currentIndex].isUpdatable() != columns[currentIndex - 1].isUpdatable() ) {
throw new AnnotationException(
"Mixing updatable and non updatable columns in a property is not allowed: " + propertyName
);
}*/
if ( !columns[currentIndex].getTable().equals( columns[currentIndex - 1].getTable() ) ) {
throw new AnnotationException(
"Mixing different tables in a property is not allowed: " + propertyName
);
}
}
}
}
Does not work…
Hibernate:
insert
into
REDACTED
(a, b, c, d, e, f, g, h, i, j, id, request_id)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Where as
@ManyToOne
@JoinColumns
({
@JoinColumn(name = "request_id", referencedColumnName = "request_id", insertable = false, updatable = false),
@JoinColumn(name = "parent", referencedColumnName = "id", insertable = false, updatable = false)
})
public Signature getParent()
{
return this.parent;
}
public void setParent(final Signature parent)
{
this.parent = parent;
setParent2115(parent == null ? null : parent.getId());
}
Hibernate:
insert
into
REDACTED
(a, b, c, d, parent, e, f, g, h, i, j, id, request_id)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Works.
From: Jason Pyeron [mailto:jpyeron@pdinc.us]
Sent: Friday, May 22, 2020 12:49 PM
To: 'Hibernate Dev' <hibernate-dev(a)lists.jboss.org>
Subject: HHH-6221 foreign keys with shared columns
I have been hunting around this morning trying to mitigate some issues of our schema and JPA mapping and https://hibernate.atlassian.net/browse/HHH-6221 seems most related.
This is a specific case following on §2.4.1 and the other bugs I have worked with recently.
Is there any more history on this bug than is in the comments of it and the related tickets? We are going to have to dive in and fix and was hoping to have a good survey of the landscape first.
We will make test case(s) along with some patches.
--- BREAK ---
Tracking internally as https://projects.pdinc.us/show_bug.cgi?id=2115 .
In our codebase we got here because of (edited for clarity)
@ManyToOne
@JoinColumns
({
@JoinColumn(name = "id", referencedColumnName = "request_id", insertable = false, updatable = false),
@JoinColumn(name = "head", referencedColumnName = "id")
})
Signature head;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
Long id;
Repeated column in mapping for entity: Entity column: column (should be mapped with insert="false" update="false")
Which then leads to
Mixing insertable and non insertable columns in a property is not allowed: Entity.column
at org.hibernate.cfg.Ejb3Column.checkPropertyConsistency(Ejb3Column.java:718)
At this moment, using the following workaround:
@ManyToOne
@JoinColumns
({
@JoinColumn(name = "id", referencedColumnName = "request_id", insertable = false, updatable = false),
@JoinColumn(name = "head", referencedColumnName = "id", insertable = false, updatable = false)
})
Signature head;
public void setHead(Signature head)
{
this.head = head;
// https://stackoverflow.com/a/49019669/58794
head2115 = head == null ? null : head.getId();
}
private Long head2115;
@Column(name = "head")
private Long getHead2115()
{
return head2115;
}
Note: JoinFormula workaround is doubly not acceptable – 1. Nonstandard, 2. org.hibernate.mapping.Formula cannot be cast to org.hibernate.mapping.Column
3 years, 11 months
Hibernate Search 6.0.0.Final is out!
by Yoann Rodiere
Hello,
We just published the first stable release of Hibernate Search 6: version
6.0.0.Final.
With more than 900 tickets addressed
<https://hibernate.atlassian.net/issues/?jql=project%20%3D%20HSEARCH%20AND...>
over the course of 20 alphas and betas, Hibernate Search 6 really is a
major release, and it shows.
The most obvious changes: an overhauled API better suited to working with
Elasticsearch (but that still works perfectly with embedded Lucene), and
upgrades from Lucene 5 to 8 and from Elasticsearch 5.6 to 7.
But it doesn’t stop there: a safer and more concise Search DSL, easier
mapping, more powerful bridges, smarter automatic indexing, nested
documents, …
For more information (what's new, getting started, migrating, ...), see our
blog:
https://in.relation.to/2020/12/11/hibernate-search-6-0-0-Final/
Yoann Rodière
Hibernate Team
yoann(a)hibernate.org
3 years, 11 months