多个相同类型的@Embedded字段持久化后始终为null

Multiple @Embedded fields of same type are always null after persisting

我实现了以下层次结构:

Abstract Superclass: ConnectionTechnologyDetails
Subclass: AS2
Embeddable: AS2Details

与其超类相比,子类 AS2 具有额外的属性和方法。附加属性是 @Embedded 类型的 AS2Details。

当我将 AS2 子类实例保存到它的存储库时,@Embedded 字段似乎丢失了。当我打印保存的实例时,所有@Embedded 字段都是null。我不知道为什么,因为在保存到存储库之前打印会导致填充的@Embedded 字段。

坚持后的结果

  "connectionTechnologyDetails": {
        "id": 2,
        "connectionTechnologyName": "AS2",
        "senderReceiverIds": {
            "senderIDOutbound": "HLCU",
            "receiverIDOutbound": "BASF",
            "senderIdInbound": "BASF",
            "receiverIdInbound": "HLCU"
        },
        "companyTestDetails": null,
        "companyProdDetails": null,
        "hlagTestDetails": null,
        "hlagProdDetails": null,
        "testString": "testStringShowsUp"
    }

ConnectionTechnologyDetails

import javax.persistence.*;
import javax.validation.constraints.NotNull;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "TECH_TYPE")
public abstract class ConnectionTechnologyDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@OneToOne
@PrimaryKeyJoinColumn
private Connection connection;

@NotNull
private ConnectionTechnologyName connectionTechnologyName;

@Embedded
private SenderReceiverIds senderReceiverIds;

public ConnectionTechnologyDetails(ConnectionTechnologyName connectionTechnologyName, SenderReceiverIds senderReceiverIds) {
    this.connectionTechnologyName = connectionTechnologyName;
    this.senderReceiverIds = senderReceiverIds;
}

public ConnectionTechnologyDetails() {

}

public ConnectionTechnologyName getConnectionTechnologyName() {
    return connectionTechnologyName;
}

public void setConnectionTechnologyName(ConnectionTechnologyName connectionTechnologyName) {
    this.connectionTechnologyName = connectionTechnologyName;
}

public SenderReceiverIds getSenderReceiverIds() {
    return senderReceiverIds;
}

public void setSenderReceiverIds(SenderReceiverIds senderReceiverIds) {
    this.senderReceiverIds = senderReceiverIds;
}

public Long getId() {
    return id;
}

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

public enum ConnectionTechnologyName {
    SMTP,
    AS2,
    UNSECURE_FTP,
    SECURE_FTP,
    FTP_SECURE
}

@Override
public String toString() {
    return "ConnectionTechnologyDetails: Name=" +getConnectionTechnologyName().name()
            + " SenderReceiverIds=" + getSenderReceiverIds();
}

}

AS2

(甚至尝试对第一个@Embedded 字段进行硬编码。但即使这样也行不通。)

import javax.persistence.*;
import javax.validation.constraints.NotNull;

@Entity(name = "AS2")
@Table(name = "AS2")
@DiscriminatorValue("AS2")
public class AS2 extends ConnectionTechnologyDetails {
    @NotNull
    @Embedded
    private AS2Details companyTestDetails = new AS2Details("192.1.168.1",
            "ctest", "localhost:8080", "ctest2", "90", "111.00.5.4",
            "scharpe", "+9+992++*9*+", "AS3");
    @NotNull
    @Embedded
    private AS2Details companyProdDetails;
    @NotNull
    @Embedded
    private AS2Details hlagTestDetails;
    @NotNull
    @Embedded
    private AS2Details hlagProdDetails;
    private String testString;

    public AS2(ConnectionTechnologyName connectionTechnologyName, SenderReceiverIds senderReceiverIds,
               AS2Details companyTestDetails, AS2Details companyProdDetails, AS2Details hlagTestDetails,
               AS2Details hlagProdDetails) {
        super(connectionTechnologyName, senderReceiverIds);
        System.err.println("ERROR---- companyTestDetails = " + companyTestDetails);
        this.companyTestDetails = companyTestDetails;
        this.companyProdDetails = companyProdDetails;
        this.hlagTestDetails = hlagTestDetails;
        this.hlagProdDetails = hlagProdDetails;
        testString = "testStringShowsUp";
    }

    public AS2() {
        super();
    }


    public void setHlagProdDetails(AS2Details hlagProdDetails) {
        this.hlagProdDetails = hlagProdDetails;
    }

    @Override
    public String toString() {
        return "AS2 Technology: Company: " + getCompanyTestDetails() + " / " + getCompanyProdDetails() + " HLAG: " +
                getHlagTestDetails() + " " + getHlagTestDetails() + getTestString();
    }

    public AS2Details getCompanyTestDetails() {
        return companyTestDetails;
    }

    public void setCompanyTestDetails(AS2Details companyTestDetails) {
        this.companyTestDetails = companyTestDetails;
    }

    public AS2Details getCompanyProdDetails() {
        return companyProdDetails;
    }

    public void setCompanyProdDetails(AS2Details companyProdDetails) {
        this.companyProdDetails = companyProdDetails;
    }

    public AS2Details getHlagTestDetails() {
        return hlagTestDetails;
    }

    public void setHlagTestDetails(AS2Details hlagTestDetails) {
        this.hlagTestDetails = hlagTestDetails;
    }

    public AS2Details getHlagProdDetails() {
        return hlagProdDetails;
    }

    public String getTestString() {
        return testString;
    }

    public void setTestString(String testString) {
        this.testString = testString;
    }
}

AS2详细信息

import javax.persistence.Column;
import javax.persistence.Embeddable;

public class AS2Details {
    @Column(name = "ip1", insertable = false, updatable = false)
    private String ip1;
    @Column(name = "as1id1", insertable = false, updatable = false)
    private String AS2ID1;
    @Column(name = "url", insertable = false, updatable = false)
    private String url;
    @Column(name = "as2id2", insertable = false, updatable = false)
    private String AS2ID2;
    @Column(name = "port", insertable = false, updatable = false)
    private String port;
    @Column(name = "ip2", insertable = false, updatable = false)
    private String ip2;
    @Column(name = "as2sofware", insertable = false, updatable = false)
    private String AS2Software;
    @Column(name = "userid", insertable = false, updatable = false)
    private String userId;
    @Column(name = "password", insertable = false, updatable = false)
    private String password;

    public AS2Details(String ip1, String AS2ID1, String url, String AS2ID2,
                      String port, String ip2, String userId, String password, String AS2Software) {
        this.ip1 = ip1;
        this.AS2ID1 = AS2ID1;
        this.url = url;
        this.AS2ID2 = AS2ID2;
        this.port = port;
        this.ip2 = ip2;
        this.userId = userId;
        this.password = password;
        this.AS2Software = AS2Software;
    }

    public AS2Details() {

    }

    public String getIp1() {
        return ip1;
    }

    public void setIp1(String ip1) {
        this.ip1 = ip1;
    }

    public String getAS2ID1() {
        return AS2ID1;
    }

    public void setAS2ID1(String AS2ID1) {
        this.AS2ID1 = AS2ID1;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getAS2ID2() {
        return AS2ID2;
    }

    public void setAS2ID2(String AS2ID2) {
        this.AS2ID2 = AS2ID2;
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }

    public String getIp2() {
        return ip2;
    }

    public void setIp2(String ip2) {
        this.ip2 = ip2;
    }

    public String getAS2Software() {
        return AS2Software;
    }

    public void setAS2Software(String AS2Software) {
        this.AS2Software = AS2Software;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "AS2 Details: " + getAS2ID1() + getAS2ID2() + getIp1() + getIp2() + getPassword();
    }
}

在 CommandLineRunner 中创建数据

    AS2Details companyTestDetails = new AS2Details("192.1.168.1",
            "ctest", "localhost:8080", "ctest2", "90", "111.00.5.4",
            "scharpe", "+9+992++*9*+", "AS3");
    AS2Details companyProdDetails = new AS2Details("192.1.168.1",
            "cp", "localhost:8080", "cp", "90", "111.00.5.4",
            "scharpe", "+9+992++*9*+", "AS3");
    AS2Details hlagTestDetails = new AS2Details("192.1.168.1",
            "htest1", "localhost:8080", "htest2", "90", "111.00.5.4",
            "scharpe", "+9+992++*9*+", "AS3");
    AS2Details hlagProdDetails = new AS2Details("192.1.168.1",
            "hp1", "localhost:8080", "hp2", "90", "111.00.5.4",
            "scharpe", "+9+992++*9*+", "AS3");

    AS2 as2 = connectionTechnologyDetailsRepository.save(new AS2(ConnectionTechnologyDetails
            .ConnectionTechnologyName.AS2, senderReceiverIds,
            companyTestDetails, companyProdDetails, hlagTestDetails, new AS2Details()));

    logger.info("CommandLineRunner: connectionTechnology AS2: " + as2.toString());
    Connection userAs2Connection = new Connection(userRepository.findByUsername("userman").get(),
            contactDetailsRepository.findFirstByOrderByIdAsc(),
            BusinessCase.CONSIGNEE,
            as2);
    connectionRepository.save(userAs2Connection);

为什么嵌入字段为null而超类的字段被填充? 当我从子类中的构造函数中打印字段时,数据正确存在。但是它没有从构造函数保存到嵌入字段。

自己解决了

如果您映射多个相同类型的@Embedded 字段 (AS2Details),您必须覆盖它们的属性。否则,您的 table 中会出现名称冲突,因为多个列将具有相同的名称。例如,在这种情况下,您将在同一个 table .

中包含 url 列和 url 列

因此我在 AS2 class 中为每个嵌入字段添加了一个 onverride 注释。 例如第一个字段:

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name="ip1", column=@Column(name="companyTestDetails_ip1")),
        @AttributeOverride(name="AS2ID1", column=@Column(name="companyTestDetails_as2id1")),
        @AttributeOverride(name="url", column=@Column(name="companyTestDetails_url")),
        @AttributeOverride(name="AS2ID2", column=@Column(name="companyTestDetails_as2id2")),
        @AttributeOverride(name="port", column=@Column(name="companyTestDetails_port")),
        @AttributeOverride(name="ip2", column=@Column(name="companyTestDetails_ip2")),
        @AttributeOverride(name="userId", column=@Column(name="companyTestDetails_userId")),
        @AttributeOverride(name="password", column=@Column(name="companyTestDetails_password")),
        @AttributeOverride(name="AS2Software", column=@Column(name="companyTestDetails_as2software"))
})
private AS2Details companyTestDetails;