Evitando classes anemicas

12 respostas
bdoweb

Olá Pessoal,

bom estou brincando um pouco com JPA. Porém eu queria ficar evitando de criar classes anemicas que serão as VO e queria trabalhar mais pensando na OO. Então montei minhas classes assim:
@Entity
@Table(name="persons")
@Inheritance (strategy=InheritanceType.JOINED)
public class Person {
	
	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE)
	private Long id;
	@Column
	private String name;
	@Column
	private String rg;
	@Column
	private String email;
	
	private Collection<Official> offial;

	public Long getId() {
		return id;
	}

	/* Getters e Setters */ 
	
	@OneToMany(cascade={CascadeType.ALL},mappedBy="person")
	public Collection<Official> getOffial() {
		return offial;
	}

	public void setOffial(Collection<Official> offial) {
		this.offial = offial;
	}
}
E a outra classe é a seguinte:
@Entity
@Table(name="officials")
@PrimaryKeyJoinColumn(name="id")
public class Official extends Person {
	
	private EntityManagerFactory factory;
	private EntityManager manager;
	
	public Official() {
		this.factory = Persistence.createEntityManagerFactory("company");
		this.manager = factory.createEntityManager();
	}
	
	@Column
	private BigDecimal salary;
	
	@Column
	private String department;
	
	public void add () {
		EntityTransaction transaction = manager.getTransaction();
		transaction.begin();
		manager.persist(this);
		transaction.commit();
		manager.close();
	}
	/* Getters e Setters */ 
}

Ele hega a gravar as informações na tabela persons mas a de officials ele dá o seguinte erro:

[TopLink Info]: 2008.01.02 10:42:31.818--ServerSession(30432385)--TopLink, version: Oracle TopLink Essentials - 2006.8 (Build 060908) [TopLink Info]: 2008.01.02 10:42:51.068--ServerSession(30432385)--file:/E:/Java/Company/bin-company login successful ============ VOU TENTAR GRAVAR ============== [TopLink Warning]: 2008.01.02 10:42:52.849--UnitOfWork(3098834)--Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2006.8 (Build 060908)): oracle.toplink.essentials.exceptions.DatabaseException Internal Exception: java.sql.SQLException: Invalid argument value: java.io.NotSerializableExceptionError Code: 0 Call:INSERT INTO officials (MANAGER, DEPARTMENT, SALARY, FACTORY, id) VALUES (?, ?, ?, ?, ?) bind => [oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl@13c7378, TI, null, oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerFactoryImpl@1c0f2e5, 1] Query:InsertObjectQuery(company.vo.Official@49d67c) Exception in thread "main" javax.persistence.RollbackException: Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2006.8 (Build 060908)): oracle.toplink.essentials.exceptions.DatabaseException Internal Exception: java.sql.SQLException: Invalid argument value: java.io.NotSerializableExceptionError Code: 0 Call:INSERT INTO officials (MANAGER, DEPARTMENT, SALARY, FACTORY, id) VALUES (?, ?, ?, ?, ?) bind => [oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl@13c7378, TI, null, oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerFactoryImpl@1c0f2e5, 1] Query:InsertObjectQuery(company.vo.Official@49d67c) at oracle.toplink.essentials.internal.ejb.cmp3.transaction.base.EntityTransactionImpl.commit(EntityTransactionImpl.java:109) at oracle.toplink.essentials.internal.ejb.cmp3.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:45) at company.vo.Official.add(Official.java:41) at company.teste.Start.main(Start.java:19) Caused by: Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2006.8 (Build 060908)): oracle.toplink.essentials.exceptions.DatabaseException Internal Exception: java.sql.SQLException: Invalid argument value: java.io.NotSerializableExceptionError Code: 0 Call:INSERT INTO officials (MANAGER, DEPARTMENT, SALARY, FACTORY, id) VALUES (?, ?, ?, ?, ?) bind => [oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl@13c7378, TI, null, oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerFactoryImpl@1c0f2e5, 1] Query:InsertObjectQuery(company.vo.Official@49d67c) at oracle.toplink.essentials.exceptions.DatabaseException.sqlException(DatabaseException.java:303) at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:551) at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:437) at oracle.toplink.essentials.internal.sessions.AbstractSession.executeCall(AbstractSession.java:675) at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:213) at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:322) at oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:176) at oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:190) at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:457) at oracle.toplink.essentials.queryframework.InsertObjectQuery.executeCommit(InsertObjectQuery.java:74) at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.performUserDefinedWrite(DatabaseQueryMechanism.java:635) at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.performUserDefinedInsert(DatabaseQueryMechanism.java:599) at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.insertObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:495) at oracle.toplink.essentials.queryframework.WriteObjectQuery.executeCommitWithChangeSet(WriteObjectQuery.java:130) at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:283) at oracle.toplink.essentials.queryframework.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:67) at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:609) at oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:536) at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:123) at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:95) at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2218) at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:937) at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:894) at oracle.toplink.essentials.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:254) at oracle.toplink.essentials.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:175) at oracle.toplink.essentials.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:2638) at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1030) at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:357) at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1112) at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:82) at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:842) at oracle.toplink.essentials.internal.ejb.cmp3.transaction.base.EntityTransactionImpl.commit(EntityTransactionImpl.java:90) ... 3 more Caused by: java.sql.SQLException: Invalid argument value: java.io.NotSerializableException at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910) at com.mysql.jdbc.PreparedStatement.setSerializableObject(PreparedStatement.java:3185) at com.mysql.jdbc.PreparedStatement.setObject(PreparedStatement.java:2838) at oracle.toplink.essentials.internal.databaseaccess.DatabasePlatform.setPrimitiveParameterValue(DatabasePlatform.java:1399) at oracle.toplink.essentials.internal.databaseaccess.DatabasePlatform.setParameterValueInDatabaseCall(DatabasePlatform.java:1389) at oracle.toplink.essentials.internal.databaseaccess.DatabasePlatform.setParameterValueInDatabaseCall(DatabasePlatform.java:1450) at oracle.toplink.essentials.internal.databaseaccess.DatabasePlatform.setParameterValueInDatabaseCall(DatabasePlatform.java:1438) at oracle.toplink.essentials.internal.databaseaccess.DatabaseCall.prepareStatement(DatabaseCall.java:608) at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:470) ... 33 more

Alguém poderia me ajudar ????? Outra dúvida tem alguma annotation para que na classe official ele ignore as variaveis factory e manager ... pois ele está criando como se fossem campos da minha tabela e na verdade são só para a persistencia ....

Muito obrigado pessoal ....

12 Respostas

F

Para ignorar vc coloca @transient

@Transient
String nomeSobrenome;
F

Gosto do seu modo de pensar, o modelo deveria ser mais que um simples record ou struct como em Pascal e C respectivamente :wink:

bdoweb

Coloquei o @transient ele não registro os campos mas o erro do printstacktrace é o mesmo mais alguém pode me ajudar …

Desculpa não entendi sua colocação … poderia me exemplificar a maneira mais correta de fazer isso!

obrigado

F

[TopLink Info]: 2008.01.02 10:42:31.818–ServerSession(30432385)–TopLink, version: Oracle TopLink Essentials - 2006.8 (Build 06090
[TopLink Info]: 2008.01.02 10:42:51.068–ServerSession(30432385)–file:/E:/Java/Company/bin-company login successful
============ VOU TENTAR GRAVAR ==============
[TopLink Warning]: 2008.01.02 10:42:52.849–UnitOfWork(3098834)–Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2006.8 (Build 06090): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Invalid argument value: java.io.NotSerializableExceptionError Code: 0
Call:INSERT INTO officials (MANAGER, DEPARTMENT, SALARY, FACTORY, id) VALUES (?, ?, ?, ?, ?)

Ainda tenta colocar este MANAGER ?
posta o trace de novo.

O_SANTO_

Eu acredito que o erro neste cenário é por falta das classes não estarem implementando a interface Serializable.

Giulliano

até onde entendi o erro é realemnte a classe serializable

conforme erro do seu log:

Invalid argument value: java.io.NotSerializableExceptionError Code: 0

Tente implementar na sua classe person/officina a classe Serializable

public class Person implements Serializable {

}
bdoweb

Olá Pessoal,

Bom na verdade meu problema era só colocar o @Transient.

@Transient private EntityManagerFactory factory; @Transient private EntityManager manager;

mas eu precisava colocar para cada …

Obrigado pessoal…

MrDataFlex

bdoweb:
Olá Pessoal,

Bom na verdade meu problema era só colocar o @Transient.

@Transient private EntityManagerFactory factory; @Transient private EntityManager manager;

mas eu precisava colocar para cada …

Obrigado pessoal…

Apesar que você poderia estar utilizando o pattern DAO para manipular estes entity*´s

bdoweb

Minha dúvida é qual a vantagem de utilizar um DAO para isso?

nbluis

Leia a motivação da existência do pattern DAO.

F

DAO seria para criar uma camada de acesso aos seus dados.
Mas acho que o Hibernate já é uma boa camada :slight_smile:
Normalmente as classes são anemicas como vc bem colocou, elas só representam a info do banco
Tua arquitetura
tabela -> objeto
arquitetura com o dao
banco -> dao -> pojo
onde POJO = classe anêmica

F

O normal é utilizar um MVC que tem um DAO
usuário -> requisição -> visão -> controle -> modelo(pojo) -> DAO -> banco de dados

bom o pojo é a info do banco e ela tem que percorrer todas as camadas praticamente.

o DAO que se encarrega de passar a info do banco para um objeto.

Criado 2 de janeiro de 2008
Ultima resposta 7 de jan. de 2008
Respostas 12
Participantes 6