对单个 table 策略使用鉴别器值时,第一个插入的实体的鉴别器值为空,但该值在数据库中
When using discriminator value for single table strategy, the first inserted entity's discriminator value is null but the value is there in database
当inheritance/single table 策略使用鉴别器值时,第一个插入实体的鉴别器值为空,但该值在数据库中。
我必须重新启动服务器,以便查询结果包含鉴别器值:
package entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.MappedSuperclass;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("Null")
@Table(name="ALLUSER")
@NamedQueries({
@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u"),
@NamedQuery(name = "User.findByAccount", query = "SELECT u FROM User u WHERE u.account = :account")
})
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String account;
private String password;
private String userType;
public User() {
super();
}
public User(String account, String password) {
super();
this.account = account;
this.password = password;
}
@Id
@Column(name = "account")
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
@Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Column(name = "user_type", insertable = false, updatable = false, nullable = false)
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
@Override
public String toString() {
return account;
}
}
@Entity
@DiscriminatorValue("Normal")
@NamedQueries({
@NamedQuery(name = "NormalUser.findAll", query = "SELECT u FROM NormalUser u")
})
public class NormalUser extends User implements Serializable{
/**
*
*/
//private String account;
private static final long serialVersionUID = 1L;
private LinkedHashSet<Customer> customers;
public NormalUser() {
super();
}
@OneToMany(fetch=FetchType.EAGER, mappedBy="normalUser", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}) //eager can be optimized when deleting a normal user
public LinkedHashSet<Customer> getCustomers() {
return customers;
}
public void setCustomers(LinkedHashSet<Customer> customers) {
this.customers = customers;
}
// @Column(name = "account")
// //have to override in order to get account to use
// public String getAccount() {
// return account;
// }
//
// public void setAccount(String account) {
// this.account = account;
// }
}
如果我只是添加一个新的普通用户(子实体),那么查询这个用户类型为空的用户:
我使用 eclipse-link 作为 JPA 实现和 Java EE 三层 Web 架构。
我知道这肯定与实体管理器的工作和持久性有关,但我不知道细节。我也不知道怎么解决。欢迎任何建议!
您没有在您的实体中设置 'type' 字段,并且 JPA 不会为您设置它 - 无论如何都不会在 java 对象中设置。如果在持久化实体时未设置它,则只要该实体被缓存(本地或共享 EMF 级缓存),它就会保持未设置状态。重新启动应用程序是有效的,因为它会清除缓存,强制从数据库中加载现有实体的任何提取,其中类型是根据鉴别器列值设置的。
您可以在创建class时设置类型,或者通过在实例上调用em.refresh强制从数据库重新加载数据。但是,在这种情况下,将类型列映射为基本映射似乎很奇怪 - getType 方法应该只是 return class 的静态鉴别器值,并且无论如何都不能更改类型字符串.
当inheritance/single table 策略使用鉴别器值时,第一个插入实体的鉴别器值为空,但该值在数据库中。 我必须重新启动服务器,以便查询结果包含鉴别器值:
package entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.MappedSuperclass;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("Null")
@Table(name="ALLUSER")
@NamedQueries({
@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u"),
@NamedQuery(name = "User.findByAccount", query = "SELECT u FROM User u WHERE u.account = :account")
})
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String account;
private String password;
private String userType;
public User() {
super();
}
public User(String account, String password) {
super();
this.account = account;
this.password = password;
}
@Id
@Column(name = "account")
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
@Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Column(name = "user_type", insertable = false, updatable = false, nullable = false)
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
@Override
public String toString() {
return account;
}
}
@Entity
@DiscriminatorValue("Normal")
@NamedQueries({
@NamedQuery(name = "NormalUser.findAll", query = "SELECT u FROM NormalUser u")
})
public class NormalUser extends User implements Serializable{
/**
*
*/
//private String account;
private static final long serialVersionUID = 1L;
private LinkedHashSet<Customer> customers;
public NormalUser() {
super();
}
@OneToMany(fetch=FetchType.EAGER, mappedBy="normalUser", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}) //eager can be optimized when deleting a normal user
public LinkedHashSet<Customer> getCustomers() {
return customers;
}
public void setCustomers(LinkedHashSet<Customer> customers) {
this.customers = customers;
}
// @Column(name = "account")
// //have to override in order to get account to use
// public String getAccount() {
// return account;
// }
//
// public void setAccount(String account) {
// this.account = account;
// }
}
如果我只是添加一个新的普通用户(子实体),那么查询这个用户类型为空的用户:
我使用 eclipse-link 作为 JPA 实现和 Java EE 三层 Web 架构。 我知道这肯定与实体管理器的工作和持久性有关,但我不知道细节。我也不知道怎么解决。欢迎任何建议!
您没有在您的实体中设置 'type' 字段,并且 JPA 不会为您设置它 - 无论如何都不会在 java 对象中设置。如果在持久化实体时未设置它,则只要该实体被缓存(本地或共享 EMF 级缓存),它就会保持未设置状态。重新启动应用程序是有效的,因为它会清除缓存,强制从数据库中加载现有实体的任何提取,其中类型是根据鉴别器列值设置的。
您可以在创建class时设置类型,或者通过在实例上调用em.refresh强制从数据库重新加载数据。但是,在这种情况下,将类型列映射为基本映射似乎很奇怪 - getType 方法应该只是 return class 的静态鉴别器值,并且无论如何都不能更改类型字符串.