Issue Details (XML | Word | Printable)

Key: GDS-629
Type: Bug Bug
Status: Resolved Resolved
Resolution: Cannot Reproduce
Priority: Major Major
Assignee: Franck Wolff
Reporter: Daniel Ferreira Monteiro Alves
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
GraniteDS

Error #2173 when sending a collection (Set) of objects

Created: 08/Feb/10 09:38 PM   Updated: 09/Feb/10 02:47 PM   Resolved: 09/Feb/10 02:47 PM
Component/s: AMF3 (de)serialization
Affects Version/s: 2.1.0_RC2
Fix Version/s: None

Environment:
Glashfish 3 + Spring + Hibernate
(Using JPA annotations + Pure Hibernate 3 (SessionFactory => Session) for the entity management, no EntityManager).


 Description  « Hide
I have this two classes:

# Papel

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sisimob.autenticacao;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import sisimob.AbstractLongIdentity;

/**
 *
 * @author Daniel Alves
 */
@Entity
@Table(name = "papel")
@NamedQueries({
@NamedQuery(name = "findByNome", query = "from Papel where nome = :nome")
})
public class Papel extends AbstractLongIdentity implements Serializable {

@Basic(optional = false)
@Column(updatable = false)
private String nome;

public Papel() {
}

public Papel(String nome) {
this.nome = nome;
}

public String getNome() {
return nome;
}

public void setNome(String nome) {
this.nome = nome;
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Papel other = (Papel) obj;
if ((this.nome == null) ? (other.nome != null) : !this.nome.equals(other.nome)) {
return false;
}
return true;
}

@Override
public int hashCode() {
int hash = 3;
hash = 47 * hash + (this.nome != null ? this.nome.hashCode() : 0);
return hash;
}
}


# Usuario
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sisimob.autenticacao;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import sisimob.AbstractLongIdentity;
import sisimob.service.util.Utility;

/**
 *
 * @author Daniel Alves
 */
@Entity
@Table(name = "usuario")
@NamedQueries({
@NamedQuery(name = "findByLogin", query = "from Usuario u where u.username = :username and u.password = :password"),
@NamedQuery(name = "findByUsername", query="from Usuario u where u.username = :username")
})
public class Usuario extends AbstractLongIdentity implements Serializable {

public Usuario() {
papeis = new HashSet<Papel>();
}

public Usuario(String username, String password) {
this();
this.username = username;
this.password = password;
}
/**
* Nome de usuário
*/
@Basic(optional = false)
@Column(updatable = false)
private String username;
/**
* Senha
*/
@Basic(optional = false)
@Column(updatable = true)
private String password;
/**
* Papéis do usuário.
*/
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "usuario_papel",
joinColumns = @JoinColumn(name = "usuario_id", nullable = false),
inverseJoinColumns = @JoinColumn(name = "papel_id", nullable = false))
private Set<Papel> papeis = new HashSet<Papel>();

public Set<Papel> getPapeis() {
return papeis;
}

// public void setPapeis(Set<Papel> papeis) {
// this.papeis = papeis;
// }

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

/**
* Codifica os dados do usuário e senha.
*/
public void encodeData() {
password = Utility.SHA256(password);
}
}

# The problem

When sending a persistent entity of Usuario from the server to the client, I got this error:

ArgumentError: Error #2173: Impossível ler o objeto em um fluxo. A classe org.granite.messaging.persistence.ExternalizablePersistentSet não implementa flash.utils.IExternalizable mas recebeu como alias uma classe externalizável.
at ObjectInput/readObject()
at sisimob.autenticacao::UsuarioBase/readExternal()[F:\Projetos\Imobiliaria\JSisImob\trunk\Client\SisImob\src\sisimob\autenticacao\UsuarioBase.as:63]

That in english is:Error #2173: Unable to read object in stream. The class org.granite.messaging.persistence.ExternalizablePersistentSet does not implement flash.utils.IExternalizable but is aliased to an externalizable.


The client part of UsuarioBase:

override public function readExternal(input:IDataInput):void {
    super.readExternal(input);
    if (meta::isInitialized()) {
        _papeis = input.readObject() as ListCollectionView; (LINE 63 - THE LINE OF THE ERROR)
        _password = input.readObject() as String;
        _username = input.readObject() as String;

Daniel Ferreira Monteiro Alves added a comment - 08/Feb/10 09:41 PM
I forgot to put in the environment the tide... so is Glashfish 3 + Spring + Hibernate + Tide ;)

Daniel Ferreira Monteiro Alves added a comment - 08/Feb/10 10:06 PM
Ok Frank,

After reading the GDS-85, I tried the same solution, with a little more actual strings :), and works... (put the -include-libraries "lib/granite.swc" "lib/granite-essentials.swc", on the flex builder compiler configuration).

Sorry, not a bug!


William Draï added a comment - 09/Feb/10 02:47 PM
You just need include-libraries with granite-essentials.swc. The other swc can be linked normally, you will get a smaller swf.
-include-libraries "lib/granite-essentials.swc"