Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -436,14 +436,15 @@ ImportedId createImportedId(BeanPropertyAssoc<?> owner, BeanDescriptor<?> target
}
TableJoinColumn[] cols = join.columns();
if (!idProp.isEmbedded()) {
// simple single scalar id
if (cols.length != 1) {
CoreLog.log.log(ERROR, "No Imported Id column for {0} in table {1}", idProp, join.getTable());
return null;
} else {
BeanProperty[] idProps = {idProp};
return createImportedScalar(owner, cols[0], idProps, others);
// simple single scalar id, match on the foreign column, allow extra TableJoinColumn for #3664
String matchColumn = idProp.dbColumn();
for (TableJoinColumn col : cols) {
if (matchColumn.equals(col.getForeignDbColumn())) {
return createImportedScalar(owner, col, new BeanProperty[]{idProp}, others);
}
}
CoreLog.log.log(ERROR, "No Imported Id column for {0} in table {1}", idProp, join.getTable());
return null;
} else {
// embedded id
BeanPropertyAssocOne<?> embProp = (BeanPropertyAssocOne<?>) idProp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,6 @@ private void initialiseAssocOne(String embeddedPrefix) {
throw new PersistenceException("Cannot find imported id for " + fullName() + " from " + targetDescriptor
+ ". If using native-image, possibly missing reflect-config for the Id property.");
}
if (importedId.isScalar()) {
// limit JoinColumn mapping to the @Id / primary key
TableJoinColumn[] columns = tableJoin.columns();
String foreignJoinColumn = columns[0].getForeignDbColumn();
String foreignIdColumn = targetDescriptor.idProperty().dbColumn();
if (!foreignJoinColumn.equalsIgnoreCase(foreignIdColumn)) {
throw new PersistenceException("Mapping limitation - @JoinColumn on " + fullName() + " needs to map to a primary key as per Issue #529 "
+ " - joining to " + foreignJoinColumn + " and not " + foreignIdColumn);
}
}
} else {
exportedProperties = createExported();
String delStmt = "delete from " + targetDescriptor.baseTable() + " where ";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ public void visitOneImported(BeanPropertyAssocOne<?> p) {
String dbCol = column.getLocalDbColumn();
BeanProperty importedProperty = p.findMatchImport(dbCol);
if (importedProperty == null) {
throw new RuntimeException("Imported BeanProperty not found?");
continue;
}
String columnDefn = ctx.getColumnDefn(importedProperty, true);
String refColumn = importedProperty.dbColumn();
Expand Down
45 changes: 45 additions & 0 deletions ebean-test/src/test/java/org/tests/model/m2o/MTJOrder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.tests.model.m2o;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class MTJOrder {

@Id
private long id;

@Column(name = "org_id")
private long orgId;

@Column
private String other;

public Long id() {
return id;
}

public MTJOrder setId(Long id) {
this.id = id;
return this;
}

public Long orgId() {
return orgId;
}

public MTJOrder setOrgId(Long orgId) {
this.orgId = orgId;
return this;
}

public String other() {
return other;
}

public MTJOrder setOther(String other) {
this.other = other;
return this;
}
}
47 changes: 47 additions & 0 deletions ebean-test/src/test/java/org/tests/model/m2o/MTJTrans.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.tests.model.m2o;

import jakarta.persistence.*;

@Entity
public class MTJTrans {

@Id
private long id;

@Column(name = "org_id")
private long orgId;

@ManyToOne
@JoinColumns({
@JoinColumn(name = "org_id", referencedColumnName = "org_id"), // extra join column, not strictly needed
@JoinColumn(name = "order_id", referencedColumnName = "id")
})
private MTJOrder order;

public Long id() {
return id;
}

public MTJTrans setId(Long id) {
this.id = id;
return this;
}

public Long orgId() {
return orgId;
}

public MTJTrans setOrgId(Long orgId) {
this.orgId = orgId;
return this;
}

public MTJOrder order() {
return order;
}

public MTJTrans setOrder(MTJOrder order) {
this.order = order;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.tests.model.m2o;

import io.ebean.DB;
import io.ebean.test.LoggedSql;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

class TestMTJoinColumns {

@Test
void test() {
MTJTrans parent = new MTJTrans();
parent.setOrgId(51L);

DB.save(parent);

MTJTrans found = DB.find(MTJTrans.class)
.setId(parent.id())
.fetch("order")
.findOne();

assertThat(found.order()).isNull();

var order = new MTJOrder()
.setOrgId(51L)
.setOther("some");
DB.save(order);
found.setOrder(order);
DB.save(found);

LoggedSql.start();
MTJTrans found2 = DB.find(MTJTrans.class)
.setId(parent.id())
.fetch("order")
.findOne();

assertThat(found2.order()).isNotNull();
assertThat(found2.order().id()).isEqualTo(order.id());
assertThat(found2.order().other()).isEqualTo("some");

List<String> sql = LoggedSql.stop();
assertThat(sql).hasSize(1);
assertThat(sql.get(0)).contains("from mtjtrans t0 left join mtjorder t1 on t1.org_id = t0.org_id and t1.id = t0.order_id where t0.id = ?");
}
}