From 50fb45dd661cb9e030be4dae83ca250825d7ea2d Mon Sep 17 00:00:00 2001 From: sando Date: Tue, 30 Jul 2024 11:29:29 +0800 Subject: [PATCH 1/2] Revert "feat[orm]: id filed can use other name with @BsonId annotation" This reverts commit e6544eaeb85e29d5a543ac0c056317069935e9c3. --- .../java/com/zfoo/orm/manager/OrmManager.java | 14 ++----- .../zfoo/orm/accessor/IdAnnotationTest.java | 41 ------------------- .../java/com/zfoo/orm/entity/MailEntity.java | 20 ++++----- 3 files changed, 14 insertions(+), 61 deletions(-) delete mode 100644 orm/src/test/java/com/zfoo/orm/accessor/IdAnnotationTest.java diff --git a/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java b/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java index d4788d00..41d44096 100644 --- a/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java +++ b/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java @@ -40,9 +40,7 @@ import com.zfoo.protocol.exception.RunException; import com.zfoo.protocol.util.*; import org.bson.Document; import org.bson.codecs.configuration.CodecRegistries; -import org.bson.codecs.pojo.Conventions; import org.bson.codecs.pojo.PojoCodecProvider; -import org.bson.codecs.pojo.annotations.BsonId; import org.bson.types.ObjectId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -105,11 +103,7 @@ public class OrmManager implements IOrmManager { allEntityCachesUsableMap.put(entityClass, false); } - var pojoCodecProvider = PojoCodecProvider.builder() - .conventions(List.of(Conventions.ANNOTATION_CONVENTION)) - .automatic(true) - .register(new MapCodecProvider()) - .build(); + var pojoCodecProvider = PojoCodecProvider.builder().automatic(true).register(new MapCodecProvider()).build(); var codecRegistry = CodecRegistries.fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), CodecRegistries.fromProviders(pojoCodecProvider)); var mongoBuilder = MongoClientSettings @@ -441,7 +435,7 @@ public class OrmManager implements IOrmManager { var getIdMethod = ReflectionUtils.getMethodByNameInPOJOClass(clazz, FieldUtils.fieldToGetMethod(clazz, idField)); var returnTypeOfGetIdMethod = getIdMethod.getReturnType(); AssertionUtils.isTrue(returnTypeOfGetIdMethod.equals(idFieldType), "[{}] getIdMethod:[{}] return type:[{}] must be equal with type id:[{}]" - , clazz.getSimpleName(), getIdMethod.getName(), returnTypeOfGetIdMethod.getName(), idFieldType.getName()); + , clazz.getSimpleName(), getIdMethod.getName(),returnTypeOfGetIdMethod.getName(), idFieldType.getName()); // 随机给id字段赋值,然后调用id()方法,看看两者的返回值是不是一样的,避免出错 var entityInstance = ReflectionUtils.newInstance(clazz); @@ -462,8 +456,8 @@ public class OrmManager implements IOrmManager { throw new RunException("orm id field only supports int long float double String ObjectId"); } - if (!idField.getName().equals("id") && !idField.isAnnotationPresent(BsonId.class)) { - throw new RunException("use @BsonId annotation to @Id filed:[{}] or rename this field with id", idField.getName()); + if (!idField.getName().equals("id")) { + throw new RunException("@Id filed must name with id"); } ReflectionUtils.makeAccessible(idField); diff --git a/orm/src/test/java/com/zfoo/orm/accessor/IdAnnotationTest.java b/orm/src/test/java/com/zfoo/orm/accessor/IdAnnotationTest.java deleted file mode 100644 index 9d1e16e9..00000000 --- a/orm/src/test/java/com/zfoo/orm/accessor/IdAnnotationTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2020 The zfoo Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and limitations under the License. - */ - -package com.zfoo.orm.accessor; - -import com.zfoo.orm.OrmContext; -import com.zfoo.orm.entity.MailEntity; -import com.zfoo.protocol.util.StringUtils; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.context.support.ClassPathXmlApplicationContext; - -import java.util.Date; - -@Ignore -public class IdAnnotationTest { - - @Test - public void batchInsertTest() { - var context = new ClassPathXmlApplicationContext("application.xml"); - for (int i = 0; i < 100; i++) { - insertMail(StringUtils.format("mail-{}", i)); - } - } - - public void insertMail(String mailId) { - OrmContext.getAccessor().delete(mailId, MailEntity.class); - var mailEntity = MailEntity.valueOf(mailId, "userName-" + mailId, "content" + mailId, new Date()); - OrmContext.getAccessor().insert(mailEntity); - } -} diff --git a/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java b/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java index 7e91db53..e5a69e05 100644 --- a/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java +++ b/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java @@ -13,10 +13,10 @@ package com.zfoo.orm.entity; +import com.zfoo.orm.anno.EntityCache; import com.zfoo.orm.anno.Id; import com.zfoo.orm.anno.Index; import com.zfoo.orm.model.IEntity; -import org.bson.codecs.pojo.annotations.BsonId; import java.util.Date; @@ -24,11 +24,11 @@ import java.util.Date; /** * @author godotg */ +@EntityCache public class MailEntity implements IEntity { @Id - @BsonId - private String mailId; + private String id; @Index(ascending = true, unique = false) private String userName; @@ -37,9 +37,9 @@ public class MailEntity implements IEntity { private Date createDate; - public static MailEntity valueOf(String mailId, String userName, String content, Date createDate) { + public static MailEntity valueOf(String id, String userName, String content, Date createDate) { var entity = new MailEntity(); - entity.mailId = mailId; + entity.id = id; entity.userName = userName; entity.content = content; entity.createDate = createDate; @@ -48,15 +48,15 @@ public class MailEntity implements IEntity { @Override public String id() { - return mailId; + return id; } - public String getMailId() { - return mailId; + public String getId() { + return id; } - public void setMailId(String mailId) { - this.mailId = mailId; + public void setId(String id) { + this.id = id; } public String getUserName() { From b2a45c703bdb56697ae734ee506dd79be6dfc5d3 Mon Sep 17 00:00:00 2001 From: sando Date: Tue, 30 Jul 2024 11:52:07 +0800 Subject: [PATCH 2/2] feat[orm]: id filed can use other name with @BsonId or @Id annotation --- orm/README.md | 2 +- orm/README_CN.md | 2 +- .../convention/ZfooAnnotationConvention.java | 45 +++++++++++++++++++ .../java/com/zfoo/orm/manager/OrmManager.java | 13 +++--- .../zfoo/orm/accessor/IdAnnotationTest.java | 41 +++++++++++++++++ .../java/com/zfoo/orm/entity/MailEntity.java | 14 +++--- 6 files changed, 102 insertions(+), 15 deletions(-) create mode 100644 orm/src/main/java/com/zfoo/orm/convention/ZfooAnnotationConvention.java create mode 100644 orm/src/test/java/com/zfoo/orm/accessor/IdAnnotationTest.java diff --git a/orm/README.md b/orm/README.md index ae3fed09..c1194564 100644 --- a/orm/README.md +++ b/orm/README.md @@ -26,7 +26,7 @@ var collection = OrmContext.getOrmManager().getCollection(UserEntity.class) #### 2. Indirect use (middle level API) to access data through the collection's simple wrapper IAccessor and IQuery interfaces - IAccessor is a data access interface - - Inserting data into the database uses the return value of the object's id() method as the primary key + - Inserting data into the database uses the field value of the object's field which marked `@Id` as the primary key ``` OrmContext.getAccessor().insert(obj) ``` diff --git a/orm/README_CN.md b/orm/README_CN.md index 2e45dcfc..dad0f0e2 100644 --- a/orm/README_CN.md +++ b/orm/README_CN.md @@ -25,7 +25,7 @@ var collection = OrmContext.getOrmManager().getCollection(UserEntity.class) #### 2. 间接使用(middle level api),通过collection的简易包装类IAccessor和IQuery接口访问数据 - IAccessor接口,为数据访问接口 - - 插入数据到数据库,会以对象的id()方法的返回值作为主键 + - 插入数据到数据库,会以对象class的@Id字段的值作为主键 ``` OrmContext.getAccessor().insert(obj) ``` diff --git a/orm/src/main/java/com/zfoo/orm/convention/ZfooAnnotationConvention.java b/orm/src/main/java/com/zfoo/orm/convention/ZfooAnnotationConvention.java new file mode 100644 index 00000000..569196a2 --- /dev/null +++ b/orm/src/main/java/com/zfoo/orm/convention/ZfooAnnotationConvention.java @@ -0,0 +1,45 @@ +package com.zfoo.orm.convention; + +import com.zfoo.orm.anno.Id; +import org.bson.BsonType; +import org.bson.codecs.pojo.ClassModelBuilder; +import org.bson.codecs.pojo.Convention; +import org.bson.codecs.pojo.PropertyModelBuilder; +import org.bson.codecs.pojo.annotations.*; + +import java.lang.annotation.Annotation; + +/** + * zfoo注解约定 + * + * @author Sando + * @version 1.0 + * @since 2024/7/30 + */ +public class ZfooAnnotationConvention implements Convention { + public static final ZfooAnnotationConvention INSTANCE = new ZfooAnnotationConvention(); + @Override + public void apply(ClassModelBuilder classModelBuilder) { + for (PropertyModelBuilder propertyModelBuilder : classModelBuilder.getPropertyModelBuilders()) { + processPropertyAnnotations(classModelBuilder, propertyModelBuilder); + } + } + + private void processPropertyAnnotations(final ClassModelBuilder classModelBuilder, + final PropertyModelBuilder propertyModelBuilder) { + for (Annotation annotation : propertyModelBuilder.getReadAnnotations()) { + if (annotation instanceof Id) { + String idPropertyName = classModelBuilder.getIdPropertyName(); + String fieldName = propertyModelBuilder.getName(); + if (idPropertyName != null && !fieldName.equals(idPropertyName)) { + // allow using @Id and @BsonId on same field + String typeName = classModelBuilder.getType().getName(); + throw new IllegalStateException("The class " + + typeName + " has more than one id property. The properties are " + + idPropertyName + " and " + fieldName); + } + classModelBuilder.idPropertyName(fieldName); + } + } + } +} diff --git a/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java b/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java index 41d44096..81c7e8c3 100644 --- a/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java +++ b/orm/src/main/java/com/zfoo/orm/manager/OrmManager.java @@ -30,6 +30,7 @@ import com.zfoo.orm.codec.MapCodecProvider; import com.zfoo.orm.config.CacheStrategy; import com.zfoo.orm.config.OrmConfig; import com.zfoo.orm.config.PersisterStrategy; +import com.zfoo.orm.convention.ZfooAnnotationConvention; import com.zfoo.orm.model.EntityDef; import com.zfoo.orm.model.IEntity; import com.zfoo.orm.model.IndexDef; @@ -40,6 +41,7 @@ import com.zfoo.protocol.exception.RunException; import com.zfoo.protocol.util.*; import org.bson.Document; import org.bson.codecs.configuration.CodecRegistries; +import org.bson.codecs.pojo.Conventions; import org.bson.codecs.pojo.PojoCodecProvider; import org.bson.types.ObjectId; import org.slf4j.Logger; @@ -103,8 +105,11 @@ public class OrmManager implements IOrmManager { allEntityCachesUsableMap.put(entityClass, false); } - var pojoCodecProvider = PojoCodecProvider.builder().automatic(true).register(new MapCodecProvider()).build(); - var codecRegistry = CodecRegistries.fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), CodecRegistries.fromProviders(pojoCodecProvider)); + var pojoCodecProvider = PojoCodecProvider.builder().automatic(true) + .conventions(List.of(Conventions.ANNOTATION_CONVENTION, ZfooAnnotationConvention.INSTANCE)) + .register(new MapCodecProvider()).build(); + var codecRegistry = CodecRegistries.fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), + CodecRegistries.fromProviders(pojoCodecProvider)); var mongoBuilder = MongoClientSettings .builder() @@ -456,10 +461,6 @@ public class OrmManager implements IOrmManager { throw new RunException("orm id field only supports int long float double String ObjectId"); } - if (!idField.getName().equals("id")) { - throw new RunException("@Id filed must name with id"); - } - ReflectionUtils.makeAccessible(idField); ReflectionUtils.setField(idField, entityInstance, idFiledValue); var idMethodOptional = Arrays.stream(ReflectionUtils.getAllMethods(clazz)).filter(it -> it.getName().equalsIgnoreCase("id")) diff --git a/orm/src/test/java/com/zfoo/orm/accessor/IdAnnotationTest.java b/orm/src/test/java/com/zfoo/orm/accessor/IdAnnotationTest.java new file mode 100644 index 00000000..9d1e16e9 --- /dev/null +++ b/orm/src/test/java/com/zfoo/orm/accessor/IdAnnotationTest.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package com.zfoo.orm.accessor; + +import com.zfoo.orm.OrmContext; +import com.zfoo.orm.entity.MailEntity; +import com.zfoo.protocol.util.StringUtils; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.util.Date; + +@Ignore +public class IdAnnotationTest { + + @Test + public void batchInsertTest() { + var context = new ClassPathXmlApplicationContext("application.xml"); + for (int i = 0; i < 100; i++) { + insertMail(StringUtils.format("mail-{}", i)); + } + } + + public void insertMail(String mailId) { + OrmContext.getAccessor().delete(mailId, MailEntity.class); + var mailEntity = MailEntity.valueOf(mailId, "userName-" + mailId, "content" + mailId, new Date()); + OrmContext.getAccessor().insert(mailEntity); + } +} diff --git a/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java b/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java index e5a69e05..bb4fed38 100644 --- a/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java +++ b/orm/src/test/java/com/zfoo/orm/entity/MailEntity.java @@ -28,7 +28,7 @@ import java.util.Date; public class MailEntity implements IEntity { @Id - private String id; + private String mailId; @Index(ascending = true, unique = false) private String userName; @@ -39,7 +39,7 @@ public class MailEntity implements IEntity { public static MailEntity valueOf(String id, String userName, String content, Date createDate) { var entity = new MailEntity(); - entity.id = id; + entity.mailId = id; entity.userName = userName; entity.content = content; entity.createDate = createDate; @@ -48,15 +48,15 @@ public class MailEntity implements IEntity { @Override public String id() { - return id; + return mailId; } - public String getId() { - return id; + public String getMailId() { + return mailId; } - public void setId(String id) { - this.id = id; + public void setMailId(String mailId) { + this.mailId = mailId; } public String getUserName() {