Vraptor + Hibernate - Injetar Entitymanager trigger hibernate[RESOLVIDO]

Boa tarde estou com um problema ao fazer uma trigger usando Hibernate e Vraptor.

Para abrir minha fabrica e as entity, eu tenho duas classes:

@Component
@ApplicationScoped
public class CriadorDeEntityManagerFactory implements
		ComponentFactory<EntityManagerFactory> {

	private EntityManagerFactory factory;
	
	@PostConstruct
	public void abre() {
		factory = Persistence.createEntityManagerFactory("Coliseu");
	}

	public EntityManagerFactory getInstance() {
		return factory;
	}

	@PreDestroy
	public void fecha() {
		this.factory.close();
	}

}

@Component
public class CriadorDeEntityManager implements ComponentFactory<EntityManager> {

	private final EntityManagerFactory factory;
	private EntityManager manager;

	public CriadorDeEntityManager(EntityManagerFactory factory) {
		this.factory = factory;
	}

	@PostConstruct
	public void abre() {
		this.manager = factory.createEntityManager();
	}

	public EntityManager getInstance() {
		return this.manager;
	}

	@PreDestroy
	public void fecha() {
		this.manager.close();
	}

}

O vraptor se encarrega de abrir e fechar as conexões.

então surgiu a necessidade de fazer trigger usando as anotações do JPA com Hibernate fiz o seguiente, criei uma classe

public class FilialitemListener {


	private final HistestoqueRepository histestoqueRepository;


	public FilialitemListener(HistestoqueRepository histestoqueRepository) {
		this.histestoqueRepository = histestoqueRepository;
	}

	@PostPersist
	void onPostPersist(Filialitem filialitem) {

		Histestoque histestoque = new Histestoque(0, filialitem, new LocalDateTime(),
				filialitem.getPrecovarejo(), filialitem.getQtdestoque(),
				filialitem.getPrecocusto(), filialitem.getCustorealvarejo(), filialitem.getLucrovarejo());

		histestoqueRepository.persist(histestoque);

	}
	
}

e no meu model esta assim:

@Entity
@EntityListeners(FilialitemListener.class)
@Table(name = "filialitem", schema = "coliseuestoque")
@SequenceGenerator(name = "coliseuestoque.gen_idfilialitem", sequenceName = "coliseuestoque.gen_idfilialitem")
public class Filialitem implements java.io.Serializable {

	private static final long serialVersionUID = 1L;
	private long idfilialitem;
	private Modulo modulo;
	private Filial filial;

...

quando eu deixo o meu listener sem o construtor da interface assim:



public class FilialitemListener {


	
	@PostPersist
	void onPostPersist(Filialitem filialitem) {

		Histestoque histestoque = new Histestoque(0, filialitem, new LocalDateTime(),
				filialitem.getPrecovarejo(), filialitem.getQtdestoque(),
				filialitem.getPrecocusto(), filialitem.getCustorealvarejo(), filialitem.getLucrovarejo());

		
	}
	
}

beleza depois de salvo o filialitem esta passando trazendo o valor e tals, o problema é que eu preciso persistir esses dados em outra tabela, aí que não estou conseguindo, porque quando eu coloco o contrutor para injetar, ele dá um pau na hora de subir.



public class FilialitemListener {


	private final HistestoqueRepository histestoqueRepository;


	public FilialitemListener(HistestoqueRepository histestoqueRepository) {
		this.histestoqueRepository = histestoqueRepository;
	}

	@PostPersist
	void onPostPersist(Filialitem filialitem) {

		Histestoque histestoque = new Histestoque(0, filialitem, new LocalDateTime(),
				filialitem.getPrecovarejo(), filialitem.getQtdestoque(),
				filialitem.getPrecocusto(), filialitem.getCustorealvarejo(), filialitem.getLucrovarejo());

		histestoqueRepository.persist(histestoque);

	}
	
}

erro:

13:44:25,494 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC00001: Failed to start service jboss.persistenceunit."CP.war#Coliseu": org.jboss.msc.service.StartException in service jboss.persistenceunit."CP.war#Coliseu": Failed to start service
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1767) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [rt.jar:1.7.0_51]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [rt.jar:1.7.0_51]
	at java.lang.Thread.run(Unknown Source) [rt.jar:1.7.0_51]
Caused by: javax.persistence.PersistenceException: Unable to create instance of br.com.coliseu.listener.FilialitemListener as a listener of beanClass
	at org.hibernate.ejb.event.CallbackResolver.resolveCallback(CallbackResolver.java:170)
	at org.hibernate.ejb.event.EntityCallbackHandler.addCallback(EntityCallbackHandler.java:123)
	at org.hibernate.ejb.event.EntityCallbackHandler.add(EntityCallbackHandler.java:62)
	at org.hibernate.ejb.event.JpaIntegrator.integrate(JpaIntegrator.java:151)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:294)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1737)
	at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:84)
	at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904)
	at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:889)
	at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
	at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:162)
	at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.start(PersistenceUnitServiceImpl.java:85)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
	... 3 more
Caused by: java.lang.InstantiationException: br.com.coliseu.listener.FilialitemListener
	at java.lang.Class.newInstance(Unknown Source) [rt.jar:1.7.0_51]
	at org.hibernate.ejb.event.CallbackResolver.resolveCallback(CallbackResolver.java:161)
	... 16 more

gostaria de saber como eu faço para injetar o Entitymanager para que eu posso manipular os dados no banco.

Obrigado!

O problema é que não é o VRaptor que instancia o listener, é o próprio hibernate. Por isso não dá pro VRaptor simplesmente injetar o repositório na classe.

Um dos jeitos de resolver, seria criando uma classe que guarde o Container do VRaptor:

@Component @ApplicationScoped
public class Gambiarra {
    private static Container container;
    public Gambiarra(Container container) {
        Gambiarra.container = container;
    }

    @PostConstruct
    public void inicializa() {
        //só pra forçar a criação do componente.
    }

    public static Container getContainer() {
         return container;
    }
}

daí com esse container vc consegue fazer:

Gambiarra.getContainer().instanceFor(SuaClasseMarota.class);

de dentro do listener.

Valeu Lucas, é eu tinha pensando em algo assim, mas não achei muito elegante, heheaeh.

então eu resolvi deixar a trigger direto no postgres mesmo.

Muito obrigado pela resposta.