记录遇到的mongDb问题

最近使用mongDb的时候,出现了一些问题。

mongDb 实体id自增

在保存实体的时候报了这个错

Cannot aotogenerate id of type java.lang.Long for entity
不能自动生成id

记录遇到的mongDb问题_第1张图片

之后就带着报错去谷歌了一下。 得到了如下结果:

Mongo ObjectIds 与 jave Long 类型不匹配。

记录遇到的mongDb问题_第2张图片

先来介绍一下MongoDB 的对象 Id(ObjectId)

ObjectId

ObjectId 是一个12字节 BSON 类型数据,有以下格式:

前4个字节表示时间戳
接下来的3个字节是机器标识码
紧接的两个字节由进程id组成(PID)
最后三个字节是随机数。

image.png

例如 62ee651f cabe7f 59dc f10372

从 MongoDB 3.4 开始(最早发布于 2016 年 12 月),ObjectId 的设计被修改了,中间 5 字节的值由原先的“机器标识码+进程号”改为单纯随机值。

a 4-byte value representing the seconds since the Unix epoch,
a 5-byte random value, and
a 3-byte counter, starting with a random value.

MongoDB中存储的文档必须有一个"_id"键。这个键的值可以是任何类型的,默认是个ObjectId对象。

在一个集合里面,每个文档都有唯一的"_id"值,来确保集合里面每个文档都能被唯一标识。

MongoDB采用ObjectId,而不是其他比较常规的做法(比如自动增加的主键)的主要原因,因为在多个 服务器上同步自动增加主键值既费力还费时。

找出原因

之后就在实体定义中发现, 我定义的id是Long类型。
由于mongoDb自动进行id自增的时候,生成的id并不能转换为Long,所以报了错

@JsonIgnoreProperties(ignoreUnknown = true)
@Document
public class System {

  @Id
  @JsonView
  private Long id;
}

之后改为String 类型之后报错消失。

在数据库中查看数据,查看到的是ObjectId类型
记录遇到的mongDb问题_第3张图片

传到前台,是string类型的数据
记录遇到的mongDb问题_第4张图片

总结

在mongoDb中想要让自动设置id的话,需要设置@Id注释,并设置为string类型。

选择使用 String 属性作为 ID,那么 Mongo 会在保存时自动为其赋值(如果它是空的)。通过选择 String,您可以获得一个由数据库管理的自动分配的 ID,而不必费心手动设置该属性。

但是目前的项目中,id都是从gitlab获取的数据,所以不需要自动设置id,若采用Long类型,并自己设置id ,得到数据就是这样, 表示 id为22。
image.png

MongoDB 持久化实体映射

在网上查了有关实体注释时,遇到了一问题。

spring-data-mongodb主要有以下常用的注解.

@Id
主键,不可重复,自带索引

@Document
标注在实体类上,类似于hibernate的entity注解,标明由mongo来维护该表

@Document(collection="mongodb 对应 collection 名")

@Document
public class System {

  @Id
  @JsonView
  private String id;

跟以前不同的是,不用@Entity注解, 用@Document注解。

@Field : 属性

存储到数据库中的字段名。

加这个注解,就是以注解的值对应mongo的key
不加这个注解,默认以参数对应mongo的key

@Field("user_name")
private String userName;

另外@CompoundIndex 联合索引和@Transient:属性就不详细说了。


关联实体

一个比较重要的点就是关联实体。

在JPA中, 我们可以用@ManyToMany,@OneToMany等注释,生成中间表等操作。

但是在mongo中,这些注释貌似并不起作用。

我在尝试添加@ManyToMany后,并没有生成中间表

@DBRef注解

而在mongo实体中,类似@OneToMany等效果的注解是: @DBRef

这个注释表示关联另一个document对象。类似于mysql的表关联。

没有加该注释的情况下,是这样子。作为普通的数据存到labels里。

记录遇到的mongDb问题_第5张图片


加了注释的情况,是这样。
这里拿了其他文章的测试结果,我还没测试

记录遇到的mongDb问题_第6张图片

可以发现而是只保存了它的id和namespace. 相当于一个引用,或者说是外键。

另外值得注意的是,
这个注解并且不会处理级联保存,你必须单独先保存@DBRef关联的对象。

你需要先respority.save(@DBRef关联的对象),然后再保存原来的对象。

这是其他文章的测试结果:
记录遇到的mongDb问题_第7张图片

小结:
看上去mongo处理的方式有点不同。但是目前项目中虽然使用了mongo,但是还在使用@Entity以及 @ManyToMany等注解,也没有发生什么报错。

但是从结果来看,@ManyToMany没有生成中间表。对mongo没有用。

restTemplate请求报错

image.png

你可能感兴趣的:(springboot)