Pregunta

Having a problem getting some data persisted with hibernate

I declare two independent classes, License and MacAddress. MacAddress can exist in its own right, but it can also be linked to to a license, when hibernate generates the underlying tables it creates a License, MacAddress and License_MacAddress table.

License

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

MacAddress

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

What Im trying to do is the following.

At some point a new license is created and a row is stored in the License table (this works correctly)

Then at a later time the license, and macaddress of the user is received. The license is retrieved from the database , we check to see if the provided macAddress is already associated with the license (multiple macaddresses can be associated with the license) and if not we then want to store the macaddress and the link nbetween license and macaddress.

But despite setting CascadeType.ALL on the @OneToMany annotation of License, no Mac Address information get's stored. I can manually save the MacAddress by saving that object seperately but still the License_MacAddress table remains empty.

Code

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;

Why can I not get the relationship between the two persisted ?

¿Fue útil?

Solución

Hibernate follows Unit of Work pattern when saving changes to the database.

You open a unit of work, apply changes to objects associated with it and Hibernate automatically saves your changes when you close the unit of work.

In practical usage of Hibernate API the concept of Unit of Work usually matches Hibernate transaction, therefore you need a transaction in this case:

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

See also:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top