Criar factory para DAO

9 respostas
bruno.costa

Meu problema é o seguinte,
Possuo a base de dados do sistema, e uma legada, em determinadas situações vou precisar utilizar um DAO que utiliza query’s no owner legado.

Porém somente 1 controller recebe este comportamento, o restante se mantém da mesma forma.

Para isso criei uma interface, onde meus dois DAO’s a implementam, retirei o @Component deles e criei uma Factory

meu Controller recebe no construtor a interface, no restante dos controllers mantive diretamente a referência à implementação do DAO, criando uma Factory para a implementação do DAO diretamente.

mas ele reclama!!

org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.cocento.erp.acs.dao.legado.LegacyBeneficiario] is defined: expected single matching bean but found 2: [com.cocento.erp.acs.infra.dao.factories.BeneficiarioDAOFactory, com.cocento.erp.acs.infra.dao.factories.LegacyBeneficiarioDAOFactory]
@Component
public class LegacyBeneficiarioDAOFactory implements ComponentFactory<LegacyBeneficiario> {

	private final Session session;
	private final AppConfig appConfig;
	private final EntityCopier entityCopier;

	public LegacyBeneficiarioDAOFactory(Session session, AppConfig appConfig, EntityCopier entityCopier) {
		this.session = session;
		this.appConfig = appConfig;
		this.entityCopier = entityCopier;
	}

	public LegacyBeneficiario getInstance() {
		LegacyBeneficiario legacy = null;
		if (appConfig.usarBeneficiarioDAOLegado()) {
			legacy = new BeneficiarioLegadoDAO(session);
		} else {
			legacy = new BeneficiarioDAO(session, entityCopier);
		}

		return legacy;
	}
}
@Component
public class BeneficiarioDAOFactory implements ComponentFactory<BeneficiarioDAO> {

	private final Session session;
	private final EntityCopier copier;

	public BeneficiarioDAOFactory(Session session, EntityCopier copier) {
		this.session = session;
		this.copier = copier;
	}

	public BeneficiarioDAO getInstance() {
		return new BeneficiarioDAO(session, copier);
	}
}

não consigo simular esse comportamento? terei que receber a interface em todos os controllers e fazer a injeção dependendo do controller e parâmetro? :confused:

9 Respostas

Lucas_Cavalcanti

Jeito fácil de resolver isso é usando a api direta do spring… crie o cara legado como:

@Repository("beneficiarioLegado")
@Scope("request")
public class BeneficiarioLegadoDAO implements ....{
  ...
}

e na hora de receber no construtor do controller, anote o parâmetro com @Qualifier(“beneficiarioLegado”), daí ele usa a implememntação legada.

se ainda assim der pau, tenta anotar o dao de verdade também com @Repository @Scope(“request”) @Primary

bruno.costa

Lucas Cavalcanti:
Jeito fácil de resolver isso é usando a api direta do spring… crie o cara legado como:

@Repository("beneficiarioLegado")
@Scope("request")
public class BeneficiarioLegadoDAO implements ....{
  ...
}

e na hora de receber no construtor do controller, anote o parâmetro com @Qualifier(“beneficiarioLegado”), daí ele usa a implememntação legada.

se ainda assim der pau, tenta anotar o dao de verdade também com @Repository @Scope(“request”) @Primary

Testando…

bruno.costa

Isso fica a nivel de compilação, se eu precisar de algo dinamico tem maneira bacana de fazer?

Lucas_Cavalcanti

não, vc precisa remover as factories… (ou tirar o @Component delas por enquanto)

bruno.costa

Não encontra.

org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.cocento.erp.acs.dao.legado.LegacyBeneficiario] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

bruno.costa

Corrigi usando
@Component
@Repository(“beneficiarioLegado”)

e

@Component
@Primary

com o @Qualifier(“beneficiarioLegado”) onde preciso do legado, como solução para desenvolvimento aqui, porém preciso fazer isso dinamicamente em produção…

Lucas_Cavalcanti

pra usar as anotações do spring precisa ter um applicationContext.xml no classpath só com o <ctx:component-scan base-package=“com.cocento.erp.acs” />

Lucas_Cavalcanti

com isso em volta:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd">
               

     <context:component-scan base-package="...."/>     
</beans>
Lucas_Cavalcanti

em produção vc não consegue saber em quais controllers vc precisa do legado?

bom, se vai ser dinâmico, vc vai precisar mesmo da factory… um jeito de saber qual é o controller é recebendo MethodInfo no construtor e pegando o ResourceMethod dele

Criado 26 de março de 2012
Ultima resposta 26 de mar. de 2012
Respostas 9
Participantes 2