多个相同类型的@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;
我实现了以下层次结构:
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;