"Save transient object before flushing" 错误
"Save transient object before flushing" error
我试图保存我的一个包含用户的实体站点,该用户已在数据库中注册,我也不想保存它。
问题是当我尝试保存网站时,出现以下错误:
org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: com.project.netmg.bo.impl.User; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.project.netmg.bo.impl.User
我想,它也试图拯救用户,但这不是我想要的。我只是想搜索好的用户并分配给网站。
java代码:
public String saveSite(@Valid @ModelAttribute SiteForm siteForm, BindingResult bindingResult, Model uiModel) {
populateSiteforSave(siteForm);
_siteService.saveSite(siteForm.getSite());
return WebConstants.REDIRECT_TO_VIEW_SITE_URL + siteForm.getSite().getSiteName();
}
private void populateSiteforSave(SiteForm siteForm) {
siteForm.getSite().setCountry((Country) _countryService.getCountryByName(siteForm.getSite().getCountry().getName()));
siteForm.getSite().setBusiness((Business) _businessService.getBusinessById(siteForm.getSite().getBusiness().getId()));
siteForm.getSite().setStatus((Status) _statusService.getStatusById(siteForm.getSite().getStatus().getId()));
if (!siteForm.getLocalItFullName().isEmpty()) {
siteForm.getSite().setLocalIt(_userService.findUserByUserFullName(siteForm.getLocalItFullName())); // user
} else {
siteForm.getSite().setLocalIt(null);
}
if (!siteForm.getRifFullName().isEmpty()) {
siteForm.getSite().setRif(_userService.findUserByUserFullName(siteForm.getRifFullName())); //user
} else {
siteForm.getSite().setRif(null);
}
if (siteForm.getSite().getLocalContact().getId() != null) {
siteForm.getSite().setLocalContact((User) _userService.findUserByUsername(siteForm.getSite().getLocalContact().getUsername())); //user
}
}
站点 class:
@Entity
@Table(name = "SITE", uniqueConstraints = { @UniqueConstraint(columnNames = { "SITE_COUNTRY_ID", "SITE_NAME" }) })
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED, withModifiedFlag = true)
public class Site implements ISite {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = -390717603276436784L;
/** The id. */
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "SITE_ID", unique = true, nullable = false)
private long id;
/** The site address. */
@Column(name = "SITE_ADDRESS", length = BusinessConstants.SITE_ADDRESS)
private String address;
/** The site analog phone number. */
@Column(name = "SITE_ANALOG_PHONE_NUMBER", length = BusinessConstants.SITE_ANALOG_PHONE_NUMBER)
private String analogPhoneNumber;
/** The site comment. */
@Column(name = "SITE_COMMENT", length = BusinessConstants.SITE_COMMENT)
private String comment;
/** The site entity code. */
@Digits(integer = 3, fraction = 0, message = "Please enter max 3 digits")
@Column(name = "SITE_ENTITY_CODE", nullable = false)
private long entityCode;
/** The site invoice code. */
@Digits(integer = 10, fraction = 0, message = "Please enter max 10 digits")
@Column(name = "SITE_INVOICE_CODE", nullable = false)
private long invoiceCode;
/** The site local it phone. */
@Column(name = "SITE_LOCAL_IT_PHONE", length = BusinessConstants.SITE_LOCAL_IT_PHONE)
private String localItPhone;
/** The site name. */
@NotBlank
@Column(name = "SITE_NAME", nullable = false, length = BusinessConstants.SITE_NAME)
private String siteName;
/** The site subnet. */
@NotBlank
@Column(name = "SITE_SUBNET", nullable = false, length = BusinessConstants.SITE_SUBNET)
private String subnet;
/** The site user number. */
@Digits(integer = 4, fraction = 0, message = "Please enter max 4 digits")
@Column(name = "SITE_USER_NUMBER")
private Long userNumber;
/** The business. */
@Valid
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SITE_BUSINESS_ID", nullable = false)
private Business business;
/** The country. */
@Valid
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "SITE_COUNTRY_ID")
private Country country;
/** The local contact. */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SITE_LOCAL_CONTACT", nullable = true)
private User localContact;
/** The local it. */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SITE_LOCAL_IT", nullable = true)
private User localIt;
/** The rif. */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SITE_RIF", nullable = true)
private User rif;
/** The status. */
@Valid
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SITE_STATUS_ID", nullable = false)
private Status status;
/** The end date. */
@Column(name = "SITE_END_DATE")
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(iso = ISO.DATE_TIME)
private Date endDate = null;
@ManyToMany(targetEntity = User.class, mappedBy = "userSites", fetch = FetchType.LAZY)
@NotAudited
private Set<IUser> siteUsers;
用户class:
@Entity
@Table(name = "USERS")
public class User implements IUser {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 6741623705511494367L;
private static final String USER_ID = "USER_ID";
/** The user id. */
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = USER_ID)
private Long id;
/** The user first name. */
@Column(name = "FIRSTNAME", length = BusinessConstants.USER_FIRSTNAME, nullable = false)
@NotNull
private String userFirstName;
/** The user last name. */
@Column(name = "LASTNAME", length = BusinessConstants.USER_LASTNAME, nullable = false)
@NotNull
private String userLastName;
/** The user email. */
@Column(name = "EMAIL", length = BusinessConstants.USER_EMAIL)
@NotNull
private String userEmail;
/** The user uid. */
@Column(name = "LOGIN", length = BusinessConstants.USER_LOGIN, nullable = false, unique = true)
@NotNull
private String username;
@Valid
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PROFILE_ID", referencedColumnName = "PROF_ID", nullable = false)
private Profile profile;
@BatchSize(size = 20)
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST }, fetch = FetchType.LAZY,targetEntity=Site.class)
@JoinTable(name = "USER_SITE",
joinColumns = { @JoinColumn(name = USER_ID, nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "SITE_ID", nullable = false) })
private Set<ISite> userSites;
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST }, fetch = FetchType.LAZY,targetEntity=Region.class)
@JoinTable(name = "USER_REGION",
joinColumns = { @JoinColumn(name = USER_ID, nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "REGION_ID", nullable = false) })
private Set<IRegion> userRegions;
@BatchSize(size = 20)
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST }, fetch = FetchType.LAZY,targetEntity=Zone.class )
@JoinTable(name = "USER_ZONE",
joinColumns = { @JoinColumn(name = USER_ID, nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "ZONE_ID", nullable = false) })
private Set<IZone> userZones;
@BatchSize(size = 20)
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST }, fetch = FetchType.LAZY,targetEntity=Country.class )
@JoinTable(name = "USER_COUNTRY",
joinColumns = { @JoinColumn(name = USER_ID, nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "COUNTRY_ID", nullable = false) })
private Set<ICountry> userCountries;
@Transient
private Collection<? extends GrantedAuthority> authorities;
@Transient
private String userFullName;
你有没有给你的实体对象映射注解cascade=CascadeType.ALL
例如:
@ManyToOne(cascade = CascadeType.ALL)
private String entityType;
你不能真正兼顾两者。如果对象图包含 User
,那么如果您的代码发生更改,它将(必须)保留下来。您是否考虑过获取 Site
(包括 User
)然后更改 localContact
并再次保留 Site
意味着什么?
如果你想让localContact
在对象图中是可设置的,但不是持久化的,那么可以用@Transient
:
注解
/** The local contact. */
@Transient
private User localContact;
希望对您有所帮助。
干杯,
我试图保存我的一个包含用户的实体站点,该用户已在数据库中注册,我也不想保存它。
问题是当我尝试保存网站时,出现以下错误:
org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: com.project.netmg.bo.impl.User; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.project.netmg.bo.impl.User
我想,它也试图拯救用户,但这不是我想要的。我只是想搜索好的用户并分配给网站。
java代码:
public String saveSite(@Valid @ModelAttribute SiteForm siteForm, BindingResult bindingResult, Model uiModel) {
populateSiteforSave(siteForm);
_siteService.saveSite(siteForm.getSite());
return WebConstants.REDIRECT_TO_VIEW_SITE_URL + siteForm.getSite().getSiteName();
}
private void populateSiteforSave(SiteForm siteForm) {
siteForm.getSite().setCountry((Country) _countryService.getCountryByName(siteForm.getSite().getCountry().getName()));
siteForm.getSite().setBusiness((Business) _businessService.getBusinessById(siteForm.getSite().getBusiness().getId()));
siteForm.getSite().setStatus((Status) _statusService.getStatusById(siteForm.getSite().getStatus().getId()));
if (!siteForm.getLocalItFullName().isEmpty()) {
siteForm.getSite().setLocalIt(_userService.findUserByUserFullName(siteForm.getLocalItFullName())); // user
} else {
siteForm.getSite().setLocalIt(null);
}
if (!siteForm.getRifFullName().isEmpty()) {
siteForm.getSite().setRif(_userService.findUserByUserFullName(siteForm.getRifFullName())); //user
} else {
siteForm.getSite().setRif(null);
}
if (siteForm.getSite().getLocalContact().getId() != null) {
siteForm.getSite().setLocalContact((User) _userService.findUserByUsername(siteForm.getSite().getLocalContact().getUsername())); //user
}
}
站点 class:
@Entity
@Table(name = "SITE", uniqueConstraints = { @UniqueConstraint(columnNames = { "SITE_COUNTRY_ID", "SITE_NAME" }) })
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED, withModifiedFlag = true)
public class Site implements ISite {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = -390717603276436784L;
/** The id. */
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "SITE_ID", unique = true, nullable = false)
private long id;
/** The site address. */
@Column(name = "SITE_ADDRESS", length = BusinessConstants.SITE_ADDRESS)
private String address;
/** The site analog phone number. */
@Column(name = "SITE_ANALOG_PHONE_NUMBER", length = BusinessConstants.SITE_ANALOG_PHONE_NUMBER)
private String analogPhoneNumber;
/** The site comment. */
@Column(name = "SITE_COMMENT", length = BusinessConstants.SITE_COMMENT)
private String comment;
/** The site entity code. */
@Digits(integer = 3, fraction = 0, message = "Please enter max 3 digits")
@Column(name = "SITE_ENTITY_CODE", nullable = false)
private long entityCode;
/** The site invoice code. */
@Digits(integer = 10, fraction = 0, message = "Please enter max 10 digits")
@Column(name = "SITE_INVOICE_CODE", nullable = false)
private long invoiceCode;
/** The site local it phone. */
@Column(name = "SITE_LOCAL_IT_PHONE", length = BusinessConstants.SITE_LOCAL_IT_PHONE)
private String localItPhone;
/** The site name. */
@NotBlank
@Column(name = "SITE_NAME", nullable = false, length = BusinessConstants.SITE_NAME)
private String siteName;
/** The site subnet. */
@NotBlank
@Column(name = "SITE_SUBNET", nullable = false, length = BusinessConstants.SITE_SUBNET)
private String subnet;
/** The site user number. */
@Digits(integer = 4, fraction = 0, message = "Please enter max 4 digits")
@Column(name = "SITE_USER_NUMBER")
private Long userNumber;
/** The business. */
@Valid
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SITE_BUSINESS_ID", nullable = false)
private Business business;
/** The country. */
@Valid
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "SITE_COUNTRY_ID")
private Country country;
/** The local contact. */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SITE_LOCAL_CONTACT", nullable = true)
private User localContact;
/** The local it. */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SITE_LOCAL_IT", nullable = true)
private User localIt;
/** The rif. */
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SITE_RIF", nullable = true)
private User rif;
/** The status. */
@Valid
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SITE_STATUS_ID", nullable = false)
private Status status;
/** The end date. */
@Column(name = "SITE_END_DATE")
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(iso = ISO.DATE_TIME)
private Date endDate = null;
@ManyToMany(targetEntity = User.class, mappedBy = "userSites", fetch = FetchType.LAZY)
@NotAudited
private Set<IUser> siteUsers;
用户class:
@Entity
@Table(name = "USERS")
public class User implements IUser {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 6741623705511494367L;
private static final String USER_ID = "USER_ID";
/** The user id. */
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = USER_ID)
private Long id;
/** The user first name. */
@Column(name = "FIRSTNAME", length = BusinessConstants.USER_FIRSTNAME, nullable = false)
@NotNull
private String userFirstName;
/** The user last name. */
@Column(name = "LASTNAME", length = BusinessConstants.USER_LASTNAME, nullable = false)
@NotNull
private String userLastName;
/** The user email. */
@Column(name = "EMAIL", length = BusinessConstants.USER_EMAIL)
@NotNull
private String userEmail;
/** The user uid. */
@Column(name = "LOGIN", length = BusinessConstants.USER_LOGIN, nullable = false, unique = true)
@NotNull
private String username;
@Valid
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PROFILE_ID", referencedColumnName = "PROF_ID", nullable = false)
private Profile profile;
@BatchSize(size = 20)
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST }, fetch = FetchType.LAZY,targetEntity=Site.class)
@JoinTable(name = "USER_SITE",
joinColumns = { @JoinColumn(name = USER_ID, nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "SITE_ID", nullable = false) })
private Set<ISite> userSites;
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST }, fetch = FetchType.LAZY,targetEntity=Region.class)
@JoinTable(name = "USER_REGION",
joinColumns = { @JoinColumn(name = USER_ID, nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "REGION_ID", nullable = false) })
private Set<IRegion> userRegions;
@BatchSize(size = 20)
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST }, fetch = FetchType.LAZY,targetEntity=Zone.class )
@JoinTable(name = "USER_ZONE",
joinColumns = { @JoinColumn(name = USER_ID, nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "ZONE_ID", nullable = false) })
private Set<IZone> userZones;
@BatchSize(size = 20)
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST }, fetch = FetchType.LAZY,targetEntity=Country.class )
@JoinTable(name = "USER_COUNTRY",
joinColumns = { @JoinColumn(name = USER_ID, nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "COUNTRY_ID", nullable = false) })
private Set<ICountry> userCountries;
@Transient
private Collection<? extends GrantedAuthority> authorities;
@Transient
private String userFullName;
你有没有给你的实体对象映射注解cascade=CascadeType.ALL
例如:
@ManyToOne(cascade = CascadeType.ALL)
private String entityType;
你不能真正兼顾两者。如果对象图包含 User
,那么如果您的代码发生更改,它将(必须)保留下来。您是否考虑过获取 Site
(包括 User
)然后更改 localContact
并再次保留 Site
意味着什么?
如果你想让localContact
在对象图中是可设置的,但不是持久化的,那么可以用@Transient
:
/** The local contact. */
@Transient
private User localContact;
希望对您有所帮助。
干杯,