From 2f233db465bf001273ac591b670bba7acc788962 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 10 Aug 2023 23:22:57 +1200 Subject: [PATCH] #3133 - For IdClass match on property name --- .../deploy/visitor/VisitProperties.java | 2 +- .../persist/dmlbind/BindableIdEmbedded.java | 13 +++++-- .../dmlbind/MatchedImportedEmbedded.java | 4 ++ .../dmlbind/MatchedImportedFactory.java | 6 +++ .../dmlbind/MatchedImportedProperty.java | 5 +++ .../dmlbind/MatchedImportedScalar.java | 5 +++ .../org/tests/cache/embeddedid/Concept2.java | 39 +++++++++++++++++++ .../embeddedid/TestCompositeForeignKey.java | 6 +++ 8 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 ebean-test/src/test/java/org/tests/cache/embeddedid/Concept2.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/visitor/VisitProperties.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/visitor/VisitProperties.java index 8997c83806..6cb2ad15d9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/visitor/VisitProperties.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/visitor/VisitProperties.java @@ -22,7 +22,7 @@ public static void visit(BeanDescriptor descriptor, BeanPropertyVisitor visit protected void visitProperties(BeanDescriptor desc, BeanPropertyVisitor propertyVisitor) { BeanProperty idProp = desc.idProperty(); - if (idProp != null) { + if (idProp != null && !idProp.name().equals("_idClass")) { visit(propertyVisitor, idProp); } BeanPropertyAssocOne unidirectional = desc.unidirectional(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdEmbedded.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdEmbedded.java index 43109f2bd1..cb1cfbc99d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdEmbedded.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdEmbedded.java @@ -64,7 +64,6 @@ public void addToUpdate(PersistRequestBean request, List list) { @Override public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException { - EntityBean idValue = (EntityBean) embId.getValue(bean); for (BeanProperty prop : props) { Object value = prop.getValue(idValue); @@ -75,14 +74,20 @@ public void dmlBind(BindableRequest request, EntityBean bean) throws SQLExceptio @Override public void dmlAppend(GenerateDmlRequest request) { - for (BeanProperty prop : props) { - request.appendColumn(prop.dbColumn()); + if (matches != null) { + // prefer the match dbColumns over the embedded property ones + for (MatchedImportedProperty match : matches) { + request.appendColumn(match.dbColumn()); + } + } else { + for (BeanProperty prop : props) { + request.appendColumn(prop.dbColumn()); + } } } @Override public boolean deriveConcatenatedId(PersistRequestBean persist) { - if (matches == null) { String m = "No matches for " + embId.fullName() + " the concatenated key columns where not found?" + " I expect that the concatenated key was null, and this bean does" diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedEmbedded.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedEmbedded.java index 60a32ea192..fa70710ad0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedEmbedded.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedEmbedded.java @@ -30,4 +30,8 @@ public void populate(EntityBean sourceBean, EntityBean embeddedId) { localProp.setValue(embeddedId, value); } + @Override + public String dbColumn() { + return localProp.dbColumn(); + } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedFactory.java index 80586ad716..99e6380433 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedFactory.java @@ -39,6 +39,12 @@ private static MatchedImportedProperty findMatch(BeanProperty prop, BeanDescript return new MatchedImportedScalar(prop, beanProperty); } } + // match on property name + for (BeanProperty beanProperty : desc.propertiesBaseScalar()) { + if (prop.name().equals(beanProperty.name())) { + return new MatchedImportedScalar(prop, beanProperty); + } + } // there was no matching assoc one property. // example UserRole bean missing assoc one to User? return null; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedProperty.java index fa8497ca54..c01710dec8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedProperty.java @@ -8,4 +8,9 @@ interface MatchedImportedProperty { * Populate the embeddedId bean from the source entity. */ void populate(EntityBean sourceBean, EntityBean embeddedId); + + /** + * Return the DB column to use. + */ + String dbColumn(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedScalar.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedScalar.java index de9907863d..0f9a08fbe5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedScalar.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedScalar.java @@ -22,4 +22,9 @@ public void populate(EntityBean sourceBean, EntityBean embeddedId) { localProp.setValue(embeddedId, value); } + @Override + public String dbColumn() { + return foreignProp.dbColumn(); + } + } diff --git a/ebean-test/src/test/java/org/tests/cache/embeddedid/Concept2.java b/ebean-test/src/test/java/org/tests/cache/embeddedid/Concept2.java new file mode 100644 index 0000000000..70a7c49096 --- /dev/null +++ b/ebean-test/src/test/java/org/tests/cache/embeddedid/Concept2.java @@ -0,0 +1,39 @@ +package org.tests.cache.embeddedid; + +import javax.persistence.*; + +@Entity +@IdClass(ConceptId.class) +@SuppressWarnings("unused") +public class Concept2 { + + @Id + @Column(name = "conn_id", nullable = false) + private String id; + + @Id + @Column(name = "conn_network_id", nullable = false) + private String networkId; + + private String label; + + + public Concept2(String networkId, String id, String label) { + this.networkId = networkId; + this.id = id; + this.label = label; + } + + public String id() { + return id; + } + + public String networkId() { + return networkId; + } + + public String label() { + return label; + } + +} diff --git a/ebean-test/src/test/java/org/tests/cache/embeddedid/TestCompositeForeignKey.java b/ebean-test/src/test/java/org/tests/cache/embeddedid/TestCompositeForeignKey.java index 0fdf069100..1925480efa 100644 --- a/ebean-test/src/test/java/org/tests/cache/embeddedid/TestCompositeForeignKey.java +++ b/ebean-test/src/test/java/org/tests/cache/embeddedid/TestCompositeForeignKey.java @@ -47,4 +47,10 @@ void createConnectionWithCompositeForeignKey() { assertThat(sql.get(3)).contains("delete from concept where (network_id,id) in"); } } + + @Test + void insert() { + var c2 = new Concept2("A", "B", "foo"); + DB.save(c2); + } }