Relacionamento OneToMany desatualizado

2 respostas
D

Estou com um problema numa busca que estou fazendo. Tenho uma classe Client e outra chamada PointRecord. Um Client tem vários PointRecord. Fiz o relacionamento de uma forma que um PointRecord possa acessar o Client que o possui ( pointRecord.getClient() ). Porém, quando faço update no Client e tento acessar qualquer membro do client pelo PointRecord, este valor está desatualizado. Por exemplo:

Antes do Update
client.getName() //Imprime Davyd
pointRecord.getClient().getName() //Imprime Davyd

Update de Davyd para David
client.getName() //Imprime David
pointRecord.getClient().getName() //Imprime Davyd

Minhas classes são:

Client.java

package com.davyd.entity;

import com.davyd.ui.ClientEditPanel;
import java.io.Serializable;
import java.sql.Date;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.persistence.*;
import javax.swing.JFrame;
import org.hibernate.annotations.Type;

@Entity
@Table(name = "client")
public class Client
{
    private Long id;
    private String firstname;
    private String surname;
    private String address;
    private String neighborhood;
    private String city;
    private String state;
    private String phone;
    private String mobile;
    private String email;
    private String observation;
    private Date birthday;
    private String code;
    private Boolean smsAllowed;
    private Boolean emailAllowed;
    
    private Set<PointRecord> pointRecords = new HashSet<>(0);

    public Client()
    {
        this("", "", "", "", "", "", "", "", "", "", "", true, true, null, null);
    }

    public Client(String firstname, String surname, String address, String neighborhood, String city, String state, String phone, String mobile, String email, String observation, String code, Boolean emailAllowed, Boolean smsAllowed, Date birthday, Set<PointRecord> pointRecords)
    {
        this.firstname = firstname;
        this.surname = surname;
        this.address = address;
        this.neighborhood = neighborhood;
        this.city = city;
        this.state = state;
        this.phone = phone;
        this.mobile = mobile;
        this.email = email;
        this.observation = observation;
        this.emailAllowed = emailAllowed;
        this.smsAllowed = smsAllowed;
        this.birthday = birthday;
        this.code = code;
        this.pointRecords = pointRecords;
    }

    @Column(name = "code", nullable = false)
    public String getCode()
    {
        return code;
    }

    public void setCode(String code)
    {
        this.code = code;
    }
    
    @Column(name = "firstname", nullable = false)
    public String getFirstname()
    {
        return firstname;
    }

    public void setFirstname(String firstname)
    {
        this.firstname = firstname;
    }

    @Column(name = "surname", nullable = false)
    public String getSurname()
    {
        return surname;
    }

    public void setSurname(String surname)
    {
        this.surname = surname;
    }

    @Id
    @GeneratedValue
    @Column(name = "client_id")
    public Long getId()
    {
        return id;
    }

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

    @Column(name = "address", nullable = false)
    public String getAddress()
    {
        return address;
    }

    public void setAddress(String address)
    {
        this.address = address;
    }

    @Column(name = "city", nullable = false)
    public String getCity()
    {
        return city;
    }

    public void setCity(String city)
    {
        this.city = city;
    }

    @Column(name = "email", nullable = false)
    public String getEmail()
    {
        return email;
    }

    public void setEmail(String email)
    {
        this.email = email;
    }

    @Column(name = "mobile", nullable = false)
    public String getMobile()
    {
        return mobile;
    }

    public void setMobile(String mobile)
    {
        this.mobile = mobile;
    }

    @Column(name = "neighborhood", nullable = false)
    public String getNeighborhood()
    {
        return neighborhood;
    }

    public void setNeighborhood(String neighborhood)
    {
        this.neighborhood = neighborhood;
    }

    @Column(name = "observation", nullable = false)
    public String getObservation()
    {
        return observation;
    }

    public void setObservation(String observation)
    {
        this.observation = observation;
    }

    @Column(name = "phone", nullable = false)
    public String getPhone()
    {
        return phone;
    }

    public void setPhone(String phone)
    {
        this.phone = phone;
    }

    @Column(name = "state", nullable = false)
    public String getState()
    {
        return state;
    }

    public void setState(String state)
    {
        this.state = state;
    }

    @Column(name = "birthday", nullable = false)
    public Date getBirthday()
    {
        return birthday;
    }

    public void setBirthday(Date birthday)
    {
        this.birthday = birthday;
    }
    
    @OneToMany(mappedBy="client")
    public Set<PointRecord> getPointRecords()
    {
        return pointRecords;
    }

    public void setPointRecords(Set<PointRecord> pointRecords)
    {
        this.pointRecords = pointRecords;
    }

    @Type(type="true_false")
    @Column(name = "email_allowed", nullable = false)
    public Boolean getEmailAllowed()
    {
        return emailAllowed;
    }

    public void setEmailAllowed(Boolean emailAllowed)
    {
        this.emailAllowed = emailAllowed;
    }

    @Type(type="true_false")
    @Column(name = "sms_allowed", nullable = false)
    public Boolean getSmsAllowed()
    {
        return smsAllowed;
    }

    public void setSmsAllowed(Boolean smsAllowed)
    {
        this.smsAllowed = smsAllowed;
    }
    
    @Transient
    public String getCompleteName()
    {
        return getFirstname() + " " + getSurname();
    }
}

PointRecord.java

package com.davyd.entity;

import java.sql.Date;
import javax.persistence.*;
import org.hibernate.annotations.Type;

@Entity
@Table(name = "point_record")
public class PointRecord
{
    private long points;
    
    private Date registeredAt;
    
    private Date expirateAt;
    
    private Long id;
    
    private Boolean emailSent;
    
    private Boolean smsSent;
    
    private Client client;
    
    public PointRecord()
    {
        this(0L, null, null, false, false);
    }
    
    public PointRecord(long points, Date registeredAt, Date expirateAt, boolean emailSent, boolean smsSent)
    {
        this.points = points;
        this.registeredAt = registeredAt;
        this.expirateAt = expirateAt;
        this.emailSent = emailSent;
        this.smsSent = smsSent;
    }

    @Type(type="true_false")
    @Column(name = "email_sent", nullable = false)
    public Boolean getEmailSent()
    {
        return emailSent;
    }

    public void setEmailSent(Boolean emailSent)
    {
        this.emailSent = emailSent;
    }

    @Type(type="true_false")
    @Column(name = "sms_sent", nullable = false)
    public Boolean getSmsSent()
    {
        return smsSent;
    }

    public void setSmsSent(Boolean smsSent)
    {
        this.smsSent = smsSent;
    }

    @Column(name = "expirate_at", nullable = false)
    public Date getExpirateAt()
    {
        return expirateAt;
    }

    public void setExpirateAt(Date expirateAt)
    {
        this.expirateAt = expirateAt;
    }
    
    @Column(name = "registered_at", nullable = false)
    public Date getRegisteredAt()
    {
        return registeredAt;
    }

    public void setRegisteredAt(Date registeredAt)
    {
        this.registeredAt = registeredAt;
    }

    @Column(name = "points", nullable = false)
    public long getPoints()
    {
        return points;
    }

    public void setPoints(long points)
    {
        this.points = points;
    }

    @Id
    @GeneratedValue
    @Column(name = "point_record_id")
    public Long getId()
    {
        return id;
    }

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

    //@ManyToOne(fetch = FetchType.LAZY)
    @ManyToOne
    @JoinColumn(name="client_id")
    public Client getClient()
    {
        return client;
    }

    public void setClient(Client client)
    {
        this.client = client;
    }
}

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
             version="1.0">
    <persistence-unit name="vmix" transaction-type="RESOURCE_LOCAL">
        
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
<!--        <class>com.davyd.entity.Client</class>-->
        <properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.connection.username" value="root" />
            <property name="hibernate.connection.password" value="root" />
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/vmix" />
            
<!--            <property name="hibernate.cache.use_query_cache" value="false"/>
            <property name="hibernate.cache.use_second_level_cache" value="false" />-->
        </properties>
    </persistence-unit>
        
        
</persistence>

GenericDao.java

public abstract class GenericDao<E> implements GenericDaoInterface<E>
{
    private EntityManager manager = null;
    private Class<E> entityClass = null;

    public GenericDao(Class<E> classe)
    {
        this.entityClass = classe;
    }

    public EntityManager getManager()
    {
        if (manager == null)
        {
            manager = Persistence.createEntityManagerFactory("vmix").createEntityManager();
        }
        return manager;
    }

    @Override
    public E find(Long id) throws EntityNotFoundException
    {
        final E result = getManager().find(entityClass, id);
        return result;
    }

    @Override
    public List<E> findAll()
    {
        return findByCriteria();
    }

    @Override
    public void create(E entity)
    {
        this.getManager().persist(entity);
        this.getManager().getTransaction().begin();
        this.getManager().getTransaction().commit();
    }

    @Override
    public void remove(Long id) throws EntityNotFoundException
    {
        E entity = find(id);
        this.getManager().remove(entity);
        this.getManager().getTransaction().begin();
        this.getManager().getTransaction().commit();
    }

    @Override
    public void update(E entity)
    {
        this.getManager().getTransaction().begin();
        this.getManager().merge(entity);
        this.getManager().getTransaction().commit();
    }
    
    protected E findAttached(Long id) throws EntityNotFoundException
    {
        E entity = this.getManager().find(this.entityClass, id);
        if (entity == null)
        {
            throw new EntityNotFoundException();
        }
        return entity;
    }

    public List<E> findByCriteria(final int firstResult,
                                  final int maxResults,
                                  final Criterion... criterion)
    {
        Session session = (Session) getManager().getDelegate();
        
        Criteria crit = session.createCriteria(entityClass);
        
        for (final Criterion c : criterion)
        {
            crit.add(c);
        }

        if (firstResult > 0)
        {
            crit.setFirstResult(firstResult);
        }

        if (maxResults > 0)
        {
            crit.setMaxResults(maxResults);
        }

        final List<E> result = crit.list();
        return result;
    }

    public List<E> findByCriteria(final Criterion... criterion)
    {
        return findByCriteria(-1, -1, criterion);
    }
}

Alguém poderia me ajudar por favor?

Abraço

2 Respostas

apferreira

Fala ae!
Talvez setando o Shared Cached Mode para ‘none’ no persistence.xml resolva seu problema.

<shared-cache-mode>NONE</shared-cache-mode>
Hebert_Coelho

apferreira:
Fala ae!
Talvez setando o Shared Cached Mode para ‘none’ no persistence.xml resolva seu problema.

<shared-cache-mode>NONE</shared-cache-mode>

Só tome cuidado ao fazer isso, o livro que eu li fala que, essa opção pode detonar com a performance da aplicação. :wink:

Criado 16 de julho de 2012
Ultima resposta 17 de jul. de 2012
Respostas 2
Participantes 3