Funcionou o esquema que estava querendo implementar, segui as dicas dos colegas. 
Criei duas interfaces com os métodos em comun para os VOs.
Interfaces:
public interface ProdutoVO {
/** Referente a tabela saldo de produtos **/
public <T extends ProdutoSaldoVO> T getProdutoSaldoVO();
/** Referente a tabela grupo de produtos **/
public GrupoProdSigaVO getGrupoProdSigaVO();
public void setGrupoProdSigaVO(GrupoProdSigaVO grupoProdSigaVO);
/** Unidade de Medida **/
public String getUnidadeMedida() ;
public void setUnidadeMedida(String unidadeMedida);
/** Código **/
public String getCodgProduto();
public void setCodgProduto(String codgProduto);
/** Descrição **/
public String getDescProduto();
public void setDescProduto(String descProduto);
/** Id **/
public Integer getIdProduto();
public void setIdProduto(Integer idProduto) ;
/** Estoque **/
public String getFlagEstoque();
public void setFlagEstoque(String flagEstoque);
/** Valor Standard **/
public BigDecimal getVlrStandard();
public void setVlrStandard(BigDecimal vlrStandard);
/** Valor do Ultimo Preço **/
public BigDecimal getVlrUltPreco();
public void setVlrUltPreco(BigDecimal vlrUltPreco);
/** D_E_L_E_T da tabela do microsiga **/
public String getDelet();
public void setDelet(String delet);
}
public interface ProdutoSaldoVO {
/** Código **/
public String getCodgProdutoSaldo();
public void setCodgProdutoSaldo(String codgProdutoSaldo);
/** Quantidade **/
public Integer getQuantidade();
public void setQuantidade(Integer quantidade);
/** Valor **/
public BigDecimal getValorProd();
public void setValorProd(BigDecimal valorProd);
/** D_E_L_E_T da tabela do microsiga **/
public String getDelet();
public void setDelet(String delet);
}
As classes VOs, ficaram com esta estrutura, distinguindo apenas pelo nome, tabela que esta mapeada e o ProdutoSaldoxxxVO que esta relacionado a ProdutoxxxVO.
@Entity
@Table(name="sb1010", schema="sigavalidacao")
@Where(clause="d_e_l_e_t_ <> '*'")
public class ProdutoUnicVO implements ProdutoVO
{
private static final long serialVersionUID = 1L;
@Column(name="r_e_c_n_o_")
private Integer idProduto;
@Id
@Column(name="b1_cod", insertable=false, updatable=false)
private String codgProduto;
@Column (name="b1_desc")
private String descProduto;
@Column (name="b1_estoque")
private String flagEstoque;
@Column (name="b1_um")
private String unidadeMedida;
@Column (name="b1_custd")
private BigDecimal vlrStandard;
@Column (name="b1_uprc")
private BigDecimal vlrUltPreco;
@Column (name="d_e_l_e_t_")
private String delet;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "b1_grupo")
private GrupoProdSigaVO grupoProdSigaVO;
@OneToOne(cascade = CascadeType.ALL/*, fetch = FetchType.LAZY*/)
@JoinColumn(name = "b1_cod")
private ProdutoSaldoUnicVO produtoSaldoVO;
/** Referente a tabela saldo de produtos **/
public ProdutoSaldoUnicVO getProdutoSaldoVO() { return produtoSaldoVO; }
public final void setProdutoSaldoVO(ProdutoSaldoUnicVO produtoSaldoVO) {
this.produtoSaldoVO = produtoSaldoVO;
}
/** Referente a tabela grupo de produtos **/
public final GrupoProdSigaVO getGrupoProdSigaVO() { return grupoProdSigaVO; }
public final void setGrupoProdSigaVO(GrupoProdSigaVO grupoProdSigaVO) {
this.grupoProdSigaVO = grupoProdSigaVO;
}
/** Unidade de Medida **/
public final String getUnidadeMedida() { return unidadeMedida; }
public final void setUnidadeMedida(String unidadeMedida) {
this.unidadeMedida = unidadeMedida;
}
/** Código **/
public final String getCodgProduto() { return codgProduto; }
public final void setCodgProduto(String codgProduto) {
this.codgProduto = codgProduto;
}
/** Descrição **/
public final String getDescProduto() { return descProduto; }
public final void setDescProduto(String descProduto) {
this.descProduto = descProduto;
}
/** Id **/
public final Integer getIdProduto() { return idProduto; }
public final void setIdProduto(Integer idProduto) {
this.idProduto = idProduto;
}
/** Estoque **/
public final String getFlagEstoque() { return flagEstoque; }
public final void setFlagEstoque(String flagEstoque) {
this.flagEstoque = flagEstoque;
}
/** Valor Standard **/
public final BigDecimal getVlrStandard() { return vlrStandard; }
public final void setVlrStandard(BigDecimal vlrStandard) {
this.vlrStandard = vlrStandard;
}
/** Valor do Ultimo Preço **/
public final BigDecimal getVlrUltPreco() { return vlrUltPreco; }
public final void setVlrUltPreco(BigDecimal vlrUltPreco) {
this.vlrUltPreco = vlrUltPreco;
}
/** D_E_L_E_T da tabela do microsiga **/
public final String getDelet() { return delet; }
public final void setDelet(String delet) {
this.delet = delet;
}
}
ProdutoSaldoxxxVO:
@Entity
@Table(name="sb2010", schema="sigavalidacao")
@Where(clause="d_e_l_e_t_ <> '*'")
public class ProdutoSaldoUnicVO implements ProdutoSaldoVO
{
@Id
@Column(name="b2_cod")
private String codgProdutoSaldo;
@Column(name="b2_qatu")
private Integer quantidade;
@Column (name="b2_cm1")
private BigDecimal valorProd;
@Column (name="d_e_l_e_t_")
private String delet;
/** Código **/
public final String getCodgProdutoSaldo() { return codgProdutoSaldo; }
public final void setCodgProdutoSaldo(String codgProdutoSaldo) {
this.codgProdutoSaldo = codgProdutoSaldo;
}
/** Quantidade **/
public final Integer getQuantidade() { return quantidade; }
public final void setQuantidade(Integer quantidade) {
this.quantidade = quantidade;
}
/** Valor **/
public final BigDecimal getValorProd() { return valorProd; }
public final void setValorProd(BigDecimal valorProd) {
this.valorProd = valorProd;
}
/** D_E_L_E_T da tabela do microsiga **/
public final String getDelet() { return delet; }
public final void setDelet(String delet) {
this.delet = delet;
}
}
DAO para consulta:
public class ProdutoDAOImpl extends HibernateGenericDAO<ProdutoUnicVO, String> implements ProdutoDAO {
/** Creates a new instance of ProdutoUnicDAOImpl **/
public ProdutoDAOImpl ()
{
super(ProdutoUnicVO.class);
}
/**
* Método que busca um ProdutoVO da tabela de produto da UNIC, UNIME ou FAMA a partir do código do produto.
*
* @param <T>
* @param objClass
* @param codgProduto
* @param tipoSolicConsProd
* @param codgUsuario
* @return
* @throws Exception
*/
public <T extends ProdutoVO> T consultarProdutoPorCodg(Class<T> objClass, String codgProduto,
String tipoSolicConsProd, Integer codgUsuario) throws Exception
{
Criteria criteria = this.getSession().createCriteria(objClass);
if(tipoSolicConsProd != null && !tipoSolicConsProd.equals("")) {
criteria.add(Restrictions.eq("flagEstoque", tipoSolicConsProd.equals("1") ? "S" : "N"));
criteria.add(Restrictions.in("grupoProdSigaVO.codgGrupoProd", this.consultaListaGrupoProdPorCodgUsuario(codgUsuario)));
criteria.add(Restrictions.eq("codgProduto", StringUtil.preencheDir(codgProduto, 15, ' ')));
} else {
criteria.add(Restrictions.eq("codgProduto", StringUtil.preencheDir(codgProduto, 15, ' ')));
}
T produtoVO = objClass.cast(criteria.uniqueResult());
this.carregaDadosProdutoVO(produtoVO);
this.verificaMaiorValorPorSolicitacao(produtoVO);
return (T) produtoVO;
}
/**
* Método que busca uma lista de Produtos da tabela de produto da UNIC, UNIME ou FAMA a partir de uma descrição.
*
* @param <T>
* @param objClass
* @param descProduto
* @param tipoSolicConsProd
* @param codgUsuario
* @return
* @throws Exception
*/
public <T extends ProdutoVO> List<T> consultarProdutoPorDesc(Class<T> objClass, String descProduto,
String tipoSolicConsProd, Integer codgUsuario) throws Exception {
List<T> produtos = null;
Criteria criteria = this.getSession().createCriteria(objClass);
if(tipoSolicConsProd != null && !tipoSolicConsProd.equals("")) {
criteria.add(Restrictions.eq("flagEstoque", tipoSolicConsProd.equals("1") ? "S" : "N"));
criteria.add(Restrictions.in("grupoProdSigaVO.codgGrupoProd", this.consultaListaGrupoProdPorCodgUsuario(codgUsuario)));
criteria.add(Expression.like("descProduto", "%"+descProduto.toUpperCase()+"%"));
} else {
criteria.add(Expression.like("descProduto", "%"+descProduto.toUpperCase()+"%"));
}
produtos = (ArrayList<T>) criteria.list();
// Altera Valores Produtos
for(ProdutoVO produtoVO: produtos) {
this.carregaDadosProdutoVO(produtoVO);
this.verificaMaiorValorPorSolicitacao(produtoVO);
}
return produtos;
}
/**
* Método listar todos produtos data tabela da UNIC, UNIME ou FAMA.
*
* @param <T>
* @param objClass
* @param tipoSolicConsProd
* @param codgUsuario
* @return
* @throws Exception
*/
public <T extends ProdutoVO> List<T> listarProdutos(Class<T> objClass, String tipoSolicConsProd,
Integer codgUsuario) throws Exception {
List<T> produtos = null;
Criteria criteria = this.getSession().createCriteria(objClass);
if(tipoSolicConsProd != null && !tipoSolicConsProd.equals("")) {
criteria.add(Restrictions.eq("flagEstoque", tipoSolicConsProd.equals("1") ? "S" : "N"));
criteria.add(Restrictions.in("grupoProdSigaVO.codgGrupoProd", this.consultaListaGrupoProdPorCodgUsuario(codgUsuario)));
}
produtos = (ArrayList<T>) criteria.list();
// Altera Valores Produtos
for(ProdutoVO produtoVO: produtos) {
this.carregaDadosProdutoVO(produtoVO);
this.verificaMaiorValorPorSolicitacao(produtoVO);
}
return produtos;
}
/**
* Seta alguns dados no produtoVO passado como parãemtro.
*
* @param produtoVO
*/
private void carregaDadosProdutoVO(ProdutoVO produtoVO) {
if(produtoVO.getFlagEstoque() != null) {
if(produtoVO.getFlagEstoque().equals("S")) {
produtoVO.setFlagEstoque("Sim");
} else {
produtoVO.setFlagEstoque("Não");
}
}
produtoVO.setCodgProduto(produtoVO.getCodgProduto().trim());
}
/**
* Verifica se o produto existe em estoque.
* Sim - Pega o maior valor entre o custo médio, ultimo preço e valor standard
* Não - Pega o valor do custo médio
*
* @param produtoVO
*/
private void verificaMaiorValorPorSolicitacao(ProdutoVO produtoVO)
{
if(produtoVO.getProdutoSaldoVO() != null ) {
float vlrProduto = 0;
if(produtoVO.getProdutoSaldoVO().getValorProd() != null) {
vlrProduto = produtoVO.getProdutoSaldoVO().getValorProd().floatValue();
}
if(produtoVO.getFlagEstoque().equals("Sim")) {
float percenVlrProd = (vlrProduto + (vlrProduto * 15 / 100));
produtoVO.getProdutoSaldoVO().setValorProd(new BigDecimal(percenVlrProd).setScale(2,BigDecimal.ROUND_HALF_DOWN));
}
else {
float vlrStandard = 0;
float vlrUltPreco = 0;
if(produtoVO.getVlrStandard() != null) {
vlrStandard = produtoVO.getVlrStandard().floatValue();
}
if(produtoVO.getVlrUltPreco() != null) {
vlrStandard = produtoVO.getVlrUltPreco().floatValue();
}
if(vlrProduto > vlrStandard && vlrProduto > vlrUltPreco) {
float percenVlrProd = (vlrProduto + (vlrProduto * 15 / 100));
produtoVO.getProdutoSaldoVO().setValorProd(new BigDecimal(percenVlrProd).setScale(2,BigDecimal.ROUND_HALF_DOWN));
}
else if(vlrStandard > vlrProduto && vlrStandard > vlrUltPreco) {
float percenVlrStand = (vlrStandard + (vlrStandard * 15 / 100));
produtoVO.getProdutoSaldoVO().setValorProd(new BigDecimal(percenVlrStand).setScale(2,BigDecimal.ROUND_HALF_DOWN));
}
else if(vlrUltPreco > vlrProduto && vlrUltPreco > vlrStandard) {
float percenVlrUltPr = (vlrUltPreco + (vlrUltPreco * 15 / 100));
produtoVO.getProdutoSaldoVO().setValorProd(new BigDecimal(percenVlrUltPr).setScale(2,BigDecimal.ROUND_HALF_DOWN));
} else {
produtoVO.getProdutoSaldoVO().setValorProd(new BigDecimal(0.0f).setScale(2,BigDecimal.ROUND_HALF_DOWN));
new BigDecimal((Double)123.456).setScale(2,BigDecimal.ROUND_HALF_DOWN);
}
}
}
}
/**
* Consulta Grupo de produtos vinculados ao usuário, por código
*
* @param codgUsuario
* @throws Exception
*/
private Object[] consultaListaGrupoProdPorCodgUsuario(Integer codgUsuario) throws Exception
{
Criteria criteria = this.getSession().createCriteria(ConfigGrupoProdVO.class);
criteria.add(Restrictions.eq("usuarioVO.codgUsuario", codgUsuario));
criteria.addOrder( Order.asc("grupoProdSigaVO.codgGrupoProd") );
List<ConfigGrupoProdVO> confGrupoProds = (ArrayList<ConfigGrupoProdVO>) criteria.list();
Object[] grupoProdsSiga = new Object[confGrupoProds.size()];
int i = 0;
for (ConfigGrupoProdVO c : confGrupoProds) {
grupoProdsSiga[i++] = StringUtil.preencheDir(c.getGrupoProdSigaVO().getCodgGrupoProd(), 4, ' ');
}
return grupoProdsSiga;
}
}
Apenas faço uma verificação, pela empresa que o usuário esta relacionado, pra realizar a chamada dos métodos de consulta:
switch (codgFilial) {
case 1: {
produtoVO = produtoService.consultarProdutoPorCodg(ProdutoUnicVO.class, codgProd, tipoSolicConsProd, codgUsuario);
break;
} case 2: {
produtoVO = produtoService.consultarProdutoPorCodg(ProdutoUnimeVO.class, codgProd, tipoSolicConsProd, codgUsuario);
break;
} case 3: {
produtoVO = produtoService.consultarProdutoPorCodg(ProdutoFamaVO.class, codgProd, tipoSolicConsProd, codgUsuario);
break;
}
}
Acho que é isso ai, caso alguém tenha uma sugestão ou alguma dica para melhorar esta implementação, posta ai para discutirmos.
OBRIGADO A TODOS PELA ATENÇÂO.