2016-06-29 7 views
1

Ich habe eine Einheit:Hibernate Updates nur ausgewählte Spalten statt alle geänderten Felder

@Entity 
@Table(name = "my_dto") 
public class MyDto implements Serializable 
{ 
    @Id 
    @GeneratedValue(generator = "uuid") 
    @GenericGenerator(name = "uuid", strategy = "uuid") 
    private String id; 
    private String displayName; 
    private String remark; 
    @Column(name = "BACKGROUND") 
    private Integer backgroundColorInt; 
    @Column(name = "FOREGROUND") 
    private Integer foregroundColorInt; 

    private boolean isBold; 
    private boolean isItalic; 
    private boolean isUnderlined; 
    @Column(name = "ISBLINKINGACTIVE") 
    private Boolean blinkingActive; 
    @Column(name = "ISBLINKINGBOLD") 
    private Boolean blinkingBold; 
    @Column(name = "ISBLINKINGITALIC") 
    private Boolean blinkingItalic; 
    @Column(name = "ISBLINKINGUNDERLINED") 
    private Boolean blinkingUnderlined; 
    @Column(name = "BLINKINGBACKGROUND") 
    private Integer blinkingBackColorInt; 
    @Column(name = "BLINKINGFOREGROUND") 
    private Integer blinkingForeColorInt; 

    @Column 
    private String createdBy; 
    @Column 
    private Date createDat; 
    @Column 
    private String changedBy; 
    @Column 
    private Date changeDat; 
    @Version 
    private int version; 

    @Transient 
    private Map< String, Object > appearanceConfig = null; 

    @PostLoad 
    public void copyMyDto2AppearanceConfig() 
    { 
     if(appearanceConfig == null) 
     { 
      appearanceConfig = new HashMap< String, Object >(); 
     } 
     appearanceConfig.put(BACKGROUND_COLOR, backgroundColorInt); 
     appearanceConfig.put(FOREGROUND_COLOR, foregroundColorInt); 
     appearanceConfig.put(FONT_STYLE, getFontStyle()); 

     appearanceConfig.put(IS_BLINKING_ACTIVE, blinkingActive); 
     HashMap< String, Object > blinkingConf = new HashMap< String, Object >(); 
     blinkingConf.put(FOREGROUND_COLOR, blinkingForeColorInt); 
     blinkingConf.put(BACKGROUND_COLOR, blinkingBackColorInt); 
     blinkingConf.put(FONT_STYLE, getBlinkingFontStyle()); 
     appearanceConfig.put(BLINKING_CONFIGURATION, blinkingConf); 
    } 

    @PreUpdate 
    public void copyAppearanceConfig2MyDto() 
    { 
     setForegroundColor((Integer)appearanceConfig.get(FOREGROUND_COLOR)); 
     setBackgroundColor((Integer)appearanceConfig.get(BACKGROUND_COLOR)); 
     setFontStyle((FontStyle[])appearanceConfig.get(FONT_STYLE)); 
     setBlinkingActive(Boolean.TRUE.equals(appearanceConfig.get(IS_BLINKING_ACTIVE))); 
     Map< String, Object > blinkingConf = 
     (Map< String, Object >)appearanceConfig.get(BLINKING_CONFIGURATION); 
     if(blinkingConf != null) 
     { 
      setBlinkingFontStyle((FontStyle[])blinkingConf.get(FONT_STYLE)); 
      setBlinkingForegroundColor((Integer)blinkingConf.get(FOREGROUND_COLOR)); 
      setBlinkingBackgroundColor((Integer)blinkingConf.get(BACKGROUND_COLOR)); 
     } 
     else 
     { 
      setBlinkingFontStyle(null); 
      setBlinkingForegroundColor((Integer)null); 
      setBlinkingBackgroundColor((Integer)null); 
     } 
    } 

    // some standard getters and setters... 
} 

ich ein stateless EJB erstellt haben, in das EAR-Paket verpackt und entfaltet es auf den JBoss-Server (Wildfly-10) . Ich bin jetzt in der Lage, die MyDto 's aus der Datenbank ohne irgendwelche Probleme zu erstellen/löschen. Was mich interessiert, ist der Update-Vorgang. Die Implementierung der EJB des Updates ist wie folgt:

@Stateless 
@Remote(MyDtoStorageServiceIf.class) 
public class MyDtoStorageService implements MyDtoStorageServiceIf 
{ 
    @PersistenceContext(unitName = "DS_MY_DTO", name = "DS_MY_DTO") 
    protected EntityManager entityManager; 
    @Override 
    public MyDto update(MyDto aMyDto) 
    { 
     MyDto myDto = entityManager.merge(aMyDto); 
     entityManager.flush(); 
     return myDto; 
    } 
    // other EJB methods, e.g. persisting new MyDto object, deleting selected MyDto from database etc. 
} 

Wenn ich versuche, die ausgewählte Zeile zu aktualisieren, es stellt sich heraus, nur displayName und remark Felder in der Datenbank aktualisiert werden, auch wenn einige andere Felder der aMyDto auch gewesen geändert. Ist es möglich, dass der Grund in den Methoden @PreUpdate und @PostLoad in der Klasse MyDto liegt? Da mir die Ideen ausgehen, möchte ich Sie bitten, auf die möglichen Gründe für dieses seltsame Verhalten hinzuweisen. Was vermisse ich am wahrscheinlichsten? Was ist das Problem?

Antwort

0

Details werden von Ihrer appearanceConfig Hash-Karte in die Felder kopiert, bevor Update passiert.

Wenn Ihre appearanceConfig Hash-Map nicht die neuesten Änderungen aufweist, überschreiben die alten Werte aus dieser Hash-Map die Änderungen.

Zu einem verwandten Hinweis, warum nicht alle Mitgliedsfelder entfernen und nur direkt in die Hash-Map schreiben? Sie könnten nur Getter und Setter haben, die Daten direkt auf die Hash-Karte setzen.