gpt4 book ai didi

java - Vaadin JPAContainer : ManytoOne relation with EmbeddedID

转载 作者:行者123 更新时间:2023-12-01 10:06:06 27 4
gpt4 key购买 nike

有问题similar但也不完全是。在这些情况下(以及在 JPAContainer 示例中),ManyToOne 关系的实体部分只有一个键。就我而言,它是一个嵌入式 id。

我的代码基于Address Book example .

以下是三个实体:

@Entity
@Table(name = "tutorial")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Tutorial.findAll", query = "SELECT t FROM Tutorial t"),
@NamedQuery(name = "Tutorial.findById", query = "SELECT t FROM Tutorial t WHERE t.tutorialPK.id = :id"),
@NamedQuery(name = "Tutorial.findByTutorialTypeId", query = "SELECT t FROM Tutorial t WHERE t.tutorialPK.tutorialTypeId = :tutorialTypeId"),
@NamedQuery(name = "Tutorial.findByMessage", query = "SELECT t FROM Tutorial t WHERE t.message = :message")})
public class Tutorial implements Serializable {

private static final long serialVersionUID = 1L;
@EmbeddedId
protected TutorialPK tutorialPK;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 245)
@Column(name = "message")
private String message;
@JoinColumn(name = "tutorial_type_id", referencedColumnName = "id", insertable = false, updatable = false)
@ManyToOne(optional = false)
private TutorialType tutorialType;

public Tutorial() {
}

public Tutorial(TutorialPK tutorialPK) {
this.tutorialPK = tutorialPK;
}

public Tutorial(TutorialPK tutorialPK, String message) {
this.tutorialPK = tutorialPK;
this.message = message;
}

public Tutorial(int id, int tutorialTypeId) {
this.tutorialPK = new TutorialPK(id, tutorialTypeId);
}

public TutorialPK getTutorialPK() {
return tutorialPK;
}

public void setTutorialPK(TutorialPK tutorialPK) {
this.tutorialPK = tutorialPK;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public TutorialType getTutorialType() {
return tutorialType;
}

public void setTutorialType(TutorialType tutorialType) {
this.tutorialType = tutorialType;
}

@Override
public int hashCode() {
int hash = 0;
hash += (tutorialPK != null ? tutorialPK.hashCode() : 0);
return hash;
}

@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Tutorial)) {
return false;
}
Tutorial other = (Tutorial) object;
if ((this.tutorialPK == null && other.tutorialPK != null) || (this.tutorialPK != null && !this.tutorialPK.equals(other.tutorialPK))) {
return false;
}
return true;
}

@Override
public String toString() {
return "games.jwrestling.server.game.db.persistence.Tutorial[ tutorialPK=" + tutorialPK + " ]";
}

}

还有EmbeddedId类:

@Embeddable
public class TutorialPK implements Serializable {

@Basic(optional = false)
@NotNull
@Column(name = "id")
private int id;
@Basic(optional = false)
@NotNull
@Column(name = "tutorial_type_id")
private int tutorialTypeId;

public TutorialPK() {
}

public TutorialPK(int id, int tutorialTypeId) {
this.id = id;
this.tutorialTypeId = tutorialTypeId;
}

public int getId() {
return id;
}

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

public int getTutorialTypeId() {
return tutorialTypeId;
}

public void setTutorialTypeId(int tutorialTypeId) {
this.tutorialTypeId = tutorialTypeId;
}

@Override
public int hashCode() {
int hash = 0;
hash += (int) id;
hash += (int) tutorialTypeId;
return hash;
}

@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof TutorialPK)) {
return false;
}
TutorialPK other = (TutorialPK) object;
if (this.id != other.id) {
return false;
}
if (this.tutorialTypeId != other.tutorialTypeId) {
return false;
}
return true;
}

@Override
public String toString() {
return "games.jwrestling.server.game.db.persistence.TutorialPK[ id=" + id + ", tutorialTypeId=" + tutorialTypeId + " ]";
}

}

还有一个:

@Entity
@Table(name = "tutorial_type")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "TutorialType.findAll", query = "SELECT t FROM TutorialType t"),
@NamedQuery(name = "TutorialType.findById", query = "SELECT t FROM TutorialType t WHERE t.id = :id"),
@NamedQuery(name = "TutorialType.findByType", query = "SELECT t FROM TutorialType t WHERE t.type = :type"),
@NamedQuery(name = "TutorialType.findByDescription", query = "SELECT t FROM TutorialType t WHERE t.description = :description")})
public class TutorialType implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@GeneratedValue(strategy = GenerationType.TABLE, generator = "TutorialTypeGen")
@TableGenerator(name = "TutorialTypeGen", table = "jwrestling_id",
pkColumnName = "tablename",
valueColumnName = "last_id",
pkColumnValue = "tutorial_type",
allocationSize = 1,
initialValue = 1)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 45)
@Column(name = "type")
private String type;
@Size(max = 245)
@Column(name = "description")
private String description;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "tutorialType")
private List<Tutorial> tutorialList;

public TutorialType() {
}

public TutorialType(Integer id) {
this.id = id;
}

public TutorialType(Integer id, String type) {
this.id = id;
this.type = type;
}

public TutorialType(String type, String desc) {
this.type = type;
this.description = desc;
}

public Integer getId() {
return id;
}

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

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

@XmlTransient
public List<Tutorial> getTutorialList() {
return tutorialList;
}

public void setTutorialList(List<Tutorial> tutorialList) {
this.tutorialList = tutorialList;
}

@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}

@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof TutorialType)) {
return false;
}
TutorialType other = (TutorialType) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}

@Override
public String toString() {
return "games.jwrestling.server.game.db.persistence.TutorialType[ id=" + id + " ]";
}

}

我设置了表单,当我编辑项目时它工作正常,但创建时出现错误,因为 TutorialPK 为空:

Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.2.v20151217-774c696): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'tutorial_type_id' cannot be null

以下是相关的 Vaadin 代码:

public final class TutorialEditor extends Window implements Button.ClickListener,
FormFieldFactory {

private final Item tutorialItem;
private final Form editorForm;
private final Button saveButton;
private final Button cancelButton;

public TutorialEditor(Item tutorialItem) {
this.tutorialItem = tutorialItem;
editorForm = new Form();
editorForm.setFormFieldFactory(this);
editorForm.setBuffered(true);
editorForm.setImmediate(true);
editorForm.setItemDataSource(tutorialItem, Arrays.asList("message",
"tutorialType"));

saveButton = new Button("Save", this);
cancelButton = new Button("Cancel", this);

editorForm.getFooter().addComponent(saveButton);
editorForm.getFooter().addComponent(cancelButton);
setSizeUndefined();
setContent(editorForm);
setCaption("New Tutorial");
}

@Override
public void buttonClick(Button.ClickEvent event) {
if (event.getButton() == saveButton) {
editorForm.commit();
fireEvent(new EditorSavedEvent(this, tutorialItem));
} else if (event.getButton() == cancelButton) {
editorForm.discard();
}
close();
}

@Override
public Field<?> createField(Item item, Object propertyId, Component uiContext) {
Field field = DefaultFieldFactory.get().createField(item, propertyId,
uiContext);
if ("tutorialType".equals(propertyId)) {
field = new TutorialTypeSelector();
} else if (field instanceof TextField) {
((TextField) field).setNullRepresentation("");
}

field.addValidator(new BeanValidator(Tutorial.class, propertyId
.toString()));

return field;
}

public void addListener(EditorSavedListener listener) {
try {
Method method = EditorSavedListener.class.getDeclaredMethod(
"editorSaved", new Class[]{EditorSavedEvent.class});
addListener(EditorSavedEvent.class, listener, method);
} catch (final java.lang.NoSuchMethodException e) {
// This should never happen
throw new java.lang.RuntimeException(
"Internal error, editor saved method not found");
}
}

public void removeListener(EditorSavedListener listener) {
removeListener(EditorSavedEvent.class, listener);
}

public static class EditorSavedEvent extends Component.Event {

private final Item savedItem;

public EditorSavedEvent(Component source, Item savedItem) {
super(source);
this.savedItem = savedItem;
}

public Item getSavedItem() {
return savedItem;
}
}

public interface EditorSavedListener extends Serializable {

public void editorSaved(EditorSavedEvent event);
}

还有一个:

class TutorialTypeSelector extends CustomField<TutorialType> {

private final JPAContainer<TutorialType> container;
private final ComboBox type = new ComboBox();

public TutorialTypeSelector() {
container = JPAContainerFactory.make(TutorialType.class,
"JWPUJNDI");
setCaption("Type");
type.setContainerDataSource(container);
type.setItemCaptionPropertyId("type");
type.addListener(new Property.ValueChangeListener() {
@Override
public void valueChange(
com.vaadin.data.Property.ValueChangeEvent event) {
/*
* Modify the actual value of the custom field.
*/
if (type.getValue() == null) {
setValue(null, false);
} else {
TutorialType entity = container
.getItem(type.getValue()).getEntity();
setValue(entity, false);
}
}
});
}

@Override
protected Component initContent() {
CssLayout cssLayout = new CssLayout();
cssLayout.addComponent(type);
return cssLayout;
}

@Override
public void setPropertyDataSource(Property newDataSource) {
super.setPropertyDataSource(newDataSource);
setTutorialType((TutorialType) newDataSource.getValue());
}

@Override
public void setValue(TutorialType newValue) throws ReadOnlyException,
Converter.ConversionException {
super.setValue(newValue);
setTutorialType(newValue);
}

private void setTutorialType(TutorialType type) {
this.type.setValue(type != null ? type.getId() : null);
}

@Override
public Class<? extends TutorialType> getType() {
return TutorialType.class;
}
}

知道如何填充此字段吗?

更新:

使用@MapsId后出错

Exception [EclipseLink-46] (Eclipse Persistence Services - 2.6.2.v20151217-774c696): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: There should be one non-read-only mapping defined for the primary key field [tutorial.tutorial_type_id].
Descriptor: RelationalDescriptor(games.jwrestling.server.game.db.persistence.Tutorial --> [DatabaseTable(tutorial)])

最佳答案

两种方式。如果使用 JPA 1.0,您将需要从引用的tutorialType 中提取值并将其手动添加到tutorial.tutorialPK.tutorialTypeId。您没有包含tutorialType实体,但如果生成了它的ID值,您可能需要在分配值之前保留它并刷新。

如果使用 JPA 2.0,您可以指定 @MapsId实体中的注释,允许 JPA 从tutorial.tutorialType 引用中设置 tuturial.tutorialPK.tutorialTypeId 值:

public class Tutorial implements Serializable {

private static final long serialVersionUID = 1L;
@EmbeddedId
protected TutorialPK tutorialPK;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 245)
@Column(name = "message")
private String message;
@MapsId("tutorialTypeId")
@ManyToOne(optional = false)
private TutorialType tutorialType;

创建教程后,您将无法更改与教程关联的教程类型 - 唯一的选择是删除现有教程并使用新值创建一个新教程类型。

关于java - Vaadin JPAContainer : ManytoOne relation with EmbeddedID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36460071/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com