2016-04-06 7 views
0

Es gibt Fragen similar aber nicht ganz. In diesen Fällen (und in den JPAContainer-Beispielen) hat der Entity-Teil der ManyToOne-Beziehung einen einzelnen Schlüssel. In meinem Fall ist es eine eingebettete ID.Vaadin JPAContainer: ManytoOne Beziehung mit EmbeddedID

Mein Code basiert auf der Address Book example.

Hier sind die drei Einheiten:

@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 + " ]"; 
    } 

} 

Und die EmbeddedId Klasse:

@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 + " ]"; 
    } 

} 

Und noch eins:

@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 + " ]"; 
    } 

} 

Ich habe das Formular eingerichtet und es funktioniert gut Wenn ich die Elemente bearbeite, bekomme ich Fehler, weil das TutorialPK null ist:

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 

Hier sind die verwandten Vaadin Code:

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); 
    } 

Und noch eins:

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; 
    } 
} 

Jede Idee, wie dieses Feld zu füllen?

Update:

Fehler nach @MapsId mit

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)]) 

Antwort

1

Zwei Möglichkeiten. Wenn Sie JPA 1.0 verwenden, müssen Sie den Wert aus dem referenzierten tutorialType abrufen und manuell zur tutorial.tutorialPK.tutorialTypeId hinzufügen. Sie haben die tutorialType-Entität nicht eingeschlossen, aber wenn der ID-Wert generiert wird, müssen Sie ihn möglicherweise beibehalten und leeren, bevor der Wert zugewiesen wird.

Wenn JPA 2.0 verwenden, können Sie die Anmerkung in Ihrem Unternehmen angeben, so dass JPA für Sie den tuturial.tutorialPK.tutorialTypeId Wert aus dem tutorial.tutorialType Bezug zu setzen:

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; 

Sie werden nicht sein Sie können den TutorialType, der zu einem Tutorial gehört, ändern, nachdem er erstellt wurde - die einzige Option ist, den bestehenden zu löschen und einen neuen mit den neuen Werten zu erstellen.

+0

Die fehlende Entity hinzugefügt, da nur die @MapsID mir Fehler gibt. – javydreamercsw

+0

Und was ist der Fehler? – Chris

+0

Siehe aktualisierte Frage. – javydreamercsw

Verwandte Themen