0

休止状態で一部のデータを永続化する際に問題が発生しました

License と MacAddress という 2 つの独立したクラスを宣言します。MacAddress はそれ自体で存在できますが、ライセンスにリンクすることもできます。hibernate が基礎となるテーブルを生成すると、License、MacAddress、および License_MacAddress テーブルが作成されます。

ライセンス

@Entity
public class License
{
    @Id
    @GeneratedValue
    private Integer      id;

    @Column(nullable = false)
    private String      license;

    @OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    private
    List<MacAddress> macAddresses;

    public Integer getId()
    {
        return id;
    }

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

    public String getLicense()
    {
        return license;
    }

    public void setLicense(String license)
    {
        this.license = license;
    }

    public List<MacAddress> getMacAddresses()
    {
        return macAddresses;
    }

    public void setMacAddresses(List<MacAddress> macAddresses)
    {
        this.macAddresses = macAddresses;
    }
}

Macアドレス

@Entity
public class MacAddress
{
    @Id
    @GeneratedValue
    private Integer      id;

    @Column(nullable = false)
    private String      macAddress;


    public Integer getId()
    {
        return id;
    }

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

    public String getMacAddress()
    {
        return macAddress;
    }

    public void setMacAddress(String macAddress)
    {
        this.macAddress = macAddress;
    }
}

私がやろうとしていることは次のとおりです。

ある時点で、新しいライセンスが作成され、License テーブルに行が格納されます (これは正しく機能します)。

その後、ライセンスとユーザーの MAC アドレスが受信されます。ライセンスはデータベースから取得され、提供された macAddress が既にライセンスに関連付けられているかどうかを確認し (複数の macaddress をライセンスに関連付けることができます)、関連付けられていない場合は、macaddress と、ライセンスと macaddress の間のリンクを保存します。

しかし、License の @OneToMany アノテーションに CascadeType.ALL を設定しても、Mac アドレス情報は保存されません。そのオブジェクトを個別に保存することで MacAddress を手動で保存できますが、それでも License_MacAddress テーブルは空のままです。

コード

session = Db.getSession();
License license = getLicense(session, licenseStr);
List<MacAddress> macAddresses = license.getMacAddresses();
for(MacAddress mac:macAddresses)
{
    if(mac.getMacAddress().equals(macAddress))
    {
        return;
    }
}

MacAddress mac = new MacAddress();
mac.setMacAddress(macAddress);
session.save(mac);
license.getMacAddresses().add(mac);
session.saveOrUpdate(license);
return;

2 つの関係を永続化できないのはなぜですか?

4

1 に答える 1

1

データベースへの変更を保存するとき、 Hibernate はUnit of Work パターンに従います。

作業ユニットを開き、それに関連付けられたオブジェクトに変更を適用すると、作業ユニットを閉じると Hibernate が自動的に変更を保存します。

Hibernate API の実際の使用では、Unit of Work の概念は通常 Hibernate トランザクションと一致するため、この場合はトランザクションが必要です。

session = Db.getSession(); 
Transaction tx = null; 
try { 
    tx = session.beginTransaction(); 
    License license = getLicense(session, licenseStr); 
    List<MacAddress> macAddresses = license.getMacAddresses(); 
    for(MacAddress mac:macAddresses) 
    { 
        if(mac.getMacAddress().equals(macAddress)) 
        { 
            return; 
        } 
    } 

    MacAddress mac = new MacAddress(); 
    mac.setMacAddress(macAddress); 
    license.getMacAddresses().add(mac);     
    tx.commit(); 
} catch (RuntimeException e) { 
    if (tx != null) tx.rollback(); 
    throw e; // or display error message 
} finally { 
    session.close(); 
}

以下も参照してください。

于 2012-09-18T12:43:11.607 に答える