为什么我的实体 ID 在更新前会发生变化?

Why my entities ids change before update?

我正在尝试更新一些实体,但即使在设置 DTO 的(并且是正确的!)值之后,它们的 ID 也会发生变化。

在我的方法中,我有以下内容:

    System.out.println("before -     parameterPojo.getId(): " + parameterPojo.getId());
    System.out.println("before -  parameterPojo.getFtpId(): " + parameterPojo.getFtpId());
    System.out.println("before -  parameterPojo.getSqlId(): " + parameterPojo.getSqlId());
    System.out.println("before - parameterPojo.getSmtpId(): " + parameterPojo.getSmtpId());

    Parameter parameter = populateParameterFromPojo(parameterPojo);

    System.out.println("after -     parameter.getId(): " + parameter.getId());
    System.out.println("after -  parameter.getFtpId(): " + parameter.getFtpConnection().getId());
    System.out.println("after -  parameter.getSqlId(): " + parameter.getSqlConnection().getId());
    System.out.println("after - parameter.getSmtpId(): " + parameter.getSmtpConnection().getId());

其中parameterPojo是数据传输对象,parameter是要持久化的对象。上述代码摘录的控制台输出为:

before -     parameterPojo.getId(): 399dc41d-54e8-41bf-a33f-d8e68422f2a2
before -  parameterPojo.getFtpId(): 7982daee-cf41-459c-85bf-1403004ecb20
before -  parameterPojo.getSqlId(): 74fd5116-cee6-4441-aa6d-af8f0501269c
before - parameterPojo.getSmtpId(): fc1bf5b9-4b54-4c03-a574-2fd2a4dd5ac2
after -     parameter.getId(): 9dfe60b0-dfed-40a5-b18c-97fe29f91feb
after -  parameter.getFtpId(): f4416b10-3d2f-43ee-a547-c69857db3ffb
after -  parameter.getSqlId(): 397dc48a-efd0-4cb5-b275-7b200c38a7c5
after - parameter.getSmtpId(): c4dd20de-630a-4e49-add4-41c40ba83de2

使用以下方法为所有实体生成 ID:

@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Column(name = "id", unique = true, length=64)
private String id;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = UUID.randomUUID().toString();
}

方法本身是:

protected Parameter populateParameterFromPojo(ParameterPojo parameterPojo) {

    Parameter parameter = parameterService.findById(parameterPojo.getId());
    FtpConnection ftpConnection = ftpService.findById(parameterPojo.getFtpId());
    SqlConnection sqlConnection = sqlService.findById(parameterPojo.getSqlId());
    SmtpConnection smtpConnection = smtpService.findById(parameterPojo.getSmtpId());

    ftpConnection.setId(parameterPojo.getFtpId());

    sqlConnection.setId(parameterPojo.getFtpId());

    smtpConnection.setId(parameterPojo.getSmtpId());

    parameter.setId(parameterPojo.getId());
    parameter.setDescription(parameterPojo.getDescription());
    parameter.setFtpConnection(ftpConnection);
    parameter.setSqlConnection(sqlConnection);
    parameter.setSmtpConnection(smtpConnection);
    parameter.setUuid(parameterPojo.getUuid());

    return parameter;
}

虽然我通过 setId(String uuid) 强制执行旧 ID,但生成的实体及其子项都获得了新 ID。

我在这里错过了什么?

您的 setter 方法正在将 id 设置为随机 UUID

public void setId(String id) {
    this.id = UUID.randomUUID().toString();
}

如果您希望能够设置它,请将其更改为

public void setId(String id) {
    this.id = id;
}

据我所知,您的 setter 每次调用时都会为您创建一个新的 UUID。

public void setId(String id) {
    this.id = UUID.randomUUID().toString();
}

虽然你传入了你的id,但是你的this.id = UUID.randomUUID正在为你创建一个新的UUID。

你的 setter 应该像这样设置相同的 id 而不是创建一个新的 id

public void setId(String id) {
    this.id = id;
}

编辑: 我建议你允许你的数据库 table/ framework ID generator (for object) 为新记录默认一个 UUID,在这种情况下你不需要为你的对象设置 ID

如果您坚持要包含它,我建议您要么创建 2 个 setter,一个带参数,另一个不带参数

public void setId(String id) {
        this.id = id;
    }

public void setId() {
        this.id = //UUID generate
    }

或者检查作为参数传入的ID是否为null/空,

public void setId(string id) {
       //if id not equals null/ empty string
            this.id = id;

       // else
            this.id = //UUID generate
        }

不过,我更愿意让数据库为新对象生成新的 UUID(如果可能的话)