Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[BUG] orm框架,主键必须命名为id,否则会出错 #108

Open
yawuaec opened this issue Jun 4, 2024 · 21 comments
Open

[BUG] orm框架,主键必须命名为id,否则会出错 #108

yawuaec opened this issue Jun 4, 2024 · 21 comments

Comments

@yawuaec
Copy link

yawuaec commented Jun 4, 2024

根本原因是 OrmContext.getAccessor().insert() 并没有把@Id注解的字段当作主键

例如主键命名为aaa

public class UserEntity implements IEntity<Long> {
    @Id
    private long aaa;

    @Override
    public Long id() {
        return aaa;
    }
}

插入数据库后会生成{_id:'xxxxxxxxxxxx',aaa=1}这样的数据

然后使用 OrmContext.getAccessor().load(1L, UserEntity.class) 查询的时候,因为_id不是1L,所以查询不到了

只有主键字段名为 id 的时候正常,这个是BUG吗,还是我使用方式错了?

@jaysunxiao
Copy link
Contributor

image

https://www.mongodb.com/docs/manual/reference/method/db.collection.insertOne/#mongodb-method-db.collection.insertOne

这个有点难办,id是mongodb的不成文规定,依赖的底层驱动并没有能修改id这个字段的方法

@jaysunxiao
Copy link
Contributor

image

就算使用底层驱动去插入,也得手动指定 _id 字段。
我这边也就只能在启动的时候做个校验,让字段名称只能是id了。

@yawuaec
Copy link
Author

yawuaec commented Jun 5, 2024

这样的话很麻烦了,每个实体类的主键都必须叫做id

比如 学生的主键是学号,教师的主键是身份证号

在代码里没法给主键命名,全部都是id,有时候实体多了不好区分每个主键的含义。

@jaysunxiao
Copy link
Contributor

确实如此,本身@id注解的含义就可以自定义名称,然后发现底层api不支持,有点违背初衷

@yawuaec
Copy link
Author

yawuaec commented Jun 5, 2024

public class UserEntity implements IEntity<Long> {

    private long id;

    @Id
    private long aaa;

    public void setAaa(long aaa) {
        this.aaa = aaa;
        this.id = aaa;
    }

    @Override
    public Long id() {
        return id;
    }
}

目前是这样解决的,还有更好的办法吗?

@jaysunxiao
Copy link
Contributor

public class UserEntity implements IEntity<Long> {

    private long id;

    @Id
    private long aaa;

    public void setAaa(long aaa) {
        this.aaa = aaa;
        this.id = aaa;
    }

    @Override
    public Long id() {
        return id;
    }
}

目前是这样解决的,还有更好的办法吗?

这样做也没有什么问题,就是多复制一个变量,问题不大

@sandogeek
Copy link
Contributor

sandogeek commented Jul 23, 2024

public class UserEntity implements IEntity<Long> {

    private long id;

    @Id
    private long aaa;

    public void setAaa(long aaa) {
        this.aaa = aaa;
        this.id = aaa;
    }

    @Override
    public Long id() {
        return id;
    }
}

目前是这样解决的,还有更好的办法吗?

这样做也没有什么问题,就是多复制一个变量,问题不大

实际上框架可以改动为将@Id标注的字段映射到_id字段,从数据库读取回来的时候也是如此,这样业务层就不用改动了

@jaysunxiao
Copy link
Contributor

public class UserEntity implements IEntity<Long> {

    private long id;

    @Id
    private long aaa;

    public void setAaa(long aaa) {
        this.aaa = aaa;
        this.id = aaa;
    }

    @Override
    public Long id() {
        return id;
    }
}

目前是这样解决的,还有更好的办法吗?

这样做也没有什么问题,就是多复制一个变量,问题不大

实际上框架可以改动为将@Id标注的字段映射到_id字段,从数据库读取回来的时候也是如此,这样业务层就不用改动了

这个会有点歧义,比如我有一个@id标注的name字段,如果强制映射到_id字段,那么数据库就找不到name这个字段了

@sandogeek
Copy link
Contributor

public class UserEntity implements IEntity<Long> {

    private long id;

    @Id
    private long aaa;

    public void setAaa(long aaa) {
        this.aaa = aaa;
        this.id = aaa;
    }

    @Override
    public Long id() {
        return id;
    }
}

目前是这样解决的,还有更好的办法吗?

这样做也没有什么问题,就是多复制一个变量,问题不大

实际上框架可以改动为将@Id标注的字段映射到_id字段,从数据库读取回来的时候也是如此,这样业务层就不用改动了

这个会有点歧义,比如我有一个@id标注的name字段,如果强制映射到_id字段,那么数据库就找不到name这个字段了

数据库没有该字段似乎也挺合理?

@sandogeek
Copy link
Contributor

sandogeek commented Jul 24, 2024

id字段自动映射到mongodb _id实际是bson.codecs带来的特性,目前bson.codecs提供了简单的办法关闭此特性。可参考此连接:MongoDB Java driver converts id field of nested object into _id
所以只需要简单修改即可实现上述映射

@jaysunxiao
Copy link
Contributor

jaysunxiao commented Jul 25, 2024

收到,等我下周有时间了来实践一下。你能改的话,也可以提pr。

@jaysunxiao
Copy link
Contributor

id字段自动映射到mongodb _id实际是bson.codecs带来的特性,目前bson.codecs提供了简单的办法关闭此特性。可参考此连接:MongoDB Java driver converts id field of nested object into _id 所以只需要简单修改即可实现上述映射

feat[orm]: id filed can use other name with @BsonId annotation

这个提交中优化了,可以不使用id作为主键名称,需要同步使用 @BsonId 这个注解

@jaysunxiao
Copy link
Contributor

jaysunxiao commented Jul 29, 2024

image

底层会做判断,非id名词的主键必须使用@BsonId这个注解,否则会报错提示

@sandogeek
Copy link
Contributor

id字段自动映射到mongodb _id实际是bson.codecs带来的特性,目前bson.codecs提供了简单的办法关闭此特性。可参考此连接:MongoDB Java driver converts id field of nested object into _id 所以只需要简单修改即可实现上述映射

feat[orm]: id filed can use other name with @BsonId annotation

这个提交中优化了,可以不使用id作为主键名称,需要同步使用 @BsonId 这个注解

这个有个值得优化的点:使用zfoo的@id和@BsonId 在不同的字段,最终会使用@BsonId 的字段作为主键。已提交了一个pr,可优化这点

@jaysunxiao
Copy link
Contributor

jaysunxiao commented Jul 30, 2024

@sandogeek 我给mongodb官方提了一个pr,如果能合进去的话直接把@id注解继承@BsonId注解就可以了。 mongo-java-driver/pull/1464

现在优先使用你的这个pr方案128 解决目前需要使用两个注解的问题

@jaysunxiao
Copy link
Contributor

jaysunxiao commented Jul 30, 2024

id字段自动映射到mongodb _id实际是bson.codecs带来的特性,目前bson.codecs提供了简单的办法关闭此特性。可参考此连接:MongoDB Java driver converts id field of nested object into _id 所以只需要简单修改即可实现上述映射

feat[orm]: id filed can use other name with @BsonId annotation
这个提交中优化了,可以不使用id作为主键名称,需要同步使用 @BsonId 这个注解

这个有个值得优化的点:使用zfoo的@id和@BsonId 在不同的字段,最终会使用@BsonId 的字段作为主键。已提交了一个pr,可优化这点

我仔细研究了一下这个Convention,和我提的这个pr mongo-java-driver/pull/1464 关系不是非常大,是不冲突的,后面即使合进去也可以继续使用你的这个pr方案128

@jaysunxiao
Copy link
Contributor

@sandogeek 另外提三点小小的优化:

  1. 注解使用instanceof Id有点奇怪,可以直接==或者equals判断,虽然最终判断正常确实不符合正常的写法
  2. IllegalStateException一般指系统环境异常换个其它的异常更好一点
  3. ZfooAnnotationConvention 去掉 Zfoo,这个大写看起来不太美观

@jaysunxiao
Copy link
Contributor

@sandogeek mongodb官方已经决定接受这个pr mongo-java-driver/pull/1464 ,后面就等版本更新,然后两者并存

@sandogeek
Copy link
Contributor

@sandogeek 另外提三点小小的优化:

  1. 注解使用instanceof Id有点奇怪,可以直接==或者equals判断,虽然最终判断正常确实不符合正常的写法
  2. IllegalStateException一般指系统环境异常换个其它的异常更好一点
  3. ZfooAnnotationConvention 去掉 Zfoo,这个大写看起来不太美观

嗯,你有空优化一波?

@jaysunxiao
Copy link
Contributor

@sandogeek 另外提三点小小的优化:

  1. 注解使用instanceof Id有点奇怪,可以直接==或者equals判断,虽然最终判断正常确实不符合正常的写法
  2. IllegalStateException一般指系统环境异常换个其它的异常更好一点
  3. ZfooAnnotationConvention 去掉 Zfoo,这个大写看起来不太美观

嗯,你有空优化一波?

这个是你提的你改吧。。。

@sandogeek
Copy link
Contributor

@sandogeek 另外提三点小小的优化:

  1. 注解使用instanceof Id有点奇怪,可以直接==或者equals判断,虽然最终判断正常确实不符合正常的写法
  2. IllegalStateException一般指系统环境异常换个其它的异常更好一点
  3. ZfooAnnotationConvention 去掉 Zfoo,这个大写看起来不太美观

嗯,你有空优化一波?

这个是你提的你改吧。。。

看起来已merge,看来得重新提pr了

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants