Problema ao criar objeto

Ola galera, estou com um problema no meu modelo de banco de dados e gostaria de ajuda.

O problema é o seguinte:

Vou criar na minha base de dados um projeto, projeto tem um set de tarefas e tarefa tem um set de atividades.

Tarefas e atividades são definidades e ja estão na minha base.

Quando vou criar projeto, escolho quais tarefas vai se compor ao meu projeto e quais atividades a minha tarefa tera. Ate ai tudo bem, o problema é quando vou persistir o objeto Projeto na minha base:

[code] Projeto pr = new Projeto();
//Nome do Projeto
pr.setNomeProjeto(nomeProjetoField.getText());

    Calendar cal = dataInicioPicker.getCalendar();
    pr.setDataIniciotProjeto(cal);

    //Set tipo do Projeto
    String aux = (String) jComboBox.getSelectedItem();
    pr.setTipo(aux);

    //Set Atividades da tarefa
    int lenght = modelTA.getSize();
    List<Tarefa> tarefas = new ArrayList<Tarefa>();
    for (int i = 0; i < lenght; i++) {
        Tarefa ta = (Tarefa) modelTA.get(i);
        Set<Atividade> sac = mapAtividadeAdicionada.get(ta);
        ta.setAtividades(sac);
        TarefaDAO tadao = new TarefaDAO();

// tadao.update(ta); //<---------------Problema se atualizo o objeto ele vai perder a lista inicial de atividades "padrão"
tarefas.add(ta);
}

    pr.setTarefas(tarefas);  //funciona!

    pr.setStatusProjeto(false);

    ProjetoDAO prdao = new ProjetoDAO();
    prdao.create(pr);[/code]

Se não ficar claro o problema eu tento explicar novamente.

Se alguém entender e tiver uma ideia de como eu posso adicionar um projeto com as tarefas e atividades eu escolher, sem modificar o padrão da relacao entre Tarefa e Atividade na minha base, por favor, me ajude.

Obrigado

Como vc não se perde nessas abreviações ? :shock:
Pra mim, algumas abreviações só confundem oq poderia ser claro.

Na sua tabela de atividades vc tem um id q diz de qual tarefa aquela atividade faz parte, correto ?
Já tentou salvar a atividade ao invés da tarefa ?

[quote=fdiaz2011]Como vc não se perde nessas abreviações ? :shock:
Pra mim, algumas abreviações só confundem oq poderia ser claro.

Na sua tabela de atividades vc tem um id q diz de qual tarefa aquela atividade faz parte, correto ?
Já tentou salvar a atividade ao invés da tarefa ?
[/quote]

Sim, correto. O relacionamento esta @OneToMany (Tarefa->Atividade) , bidirecional.
O problema é que, se eu salvar atividade, ela provavelmente replicara atividade no banco com o id’s diferentes ligado a mesma tarefa.
Então quando eu fosse filtrar os dados de tarefas e atividades para criar um banco, teria valores replicados com o mesmo id.

Seria dois tiros nos pés. Faço isso e o meu banco cresce exponencialmente.

O que pensei seria apenas uma relacao de objeto com o banco de dados.

Não sei se isso existe, mas talvez resolvesse.

Estou realmente perdido agora.

Tudo bom andrielc?

Minha principal dúvida é como esta modelado seu BD.

Pelo que entendi, uma das formas que você pode resolver isso é fazendo uma query antes de salvar/atualizar os dados retornando o id da atividade selecionada e inseri-lá na tabela da tarefa. Mostre-nos esse padrão de relação entre Tarefa e Atividade por favor.

[quote=MarcoAurelioBC]Tudo bom andrielc?

Minha principal dúvida é como esta modelado seu BD.

Pelo que entendi, uma das formas que você pode resolver isso é fazendo uma query antes de salvar/atualizar os dados retornando o id da atividade selecionada e inseri-lá na tabela da tarefa. Mostre-nos esse padrão de relação entre Tarefa e Atividade por favor.[/quote]

Ola MarcoAurelioBC, tudo bem e contigo ?

Bem, aqui vai:

[code]@Entity
public class Tarefa {

@Id
@GeneratedValue
private Long id;

private String nomeTarefa;

@OneToMany
@LazyCollection(LazyCollectionOption.FALSE)
private Set atividades = new HashSet();

//get e sets
}

@Entity
public class Atividade{

@Id  
@Column(name = "NOME_ATIVIDADE")
private String nomeAtividade;

@Column(name = "TIPO")
private String tipo;

@Column(name = "PESO")
private Double peso;

@ManyToOne
private Grupo grupo;

@ManyToOne
private Tarefa tarefa;

@ManyToMany
private Set<Pessoa> pessoas= new HashSet<Pessoa>();

@OneToMany
@LazyCollection(LazyCollectionOption.FALSE)
private Set<Fase> fases= new HashSet<Fase>();
//gets e sets

}[/code]

[quote=andrielc][quote=fdiaz2011]Como vc não se perde nessas abreviações ? :shock:
Pra mim, algumas abreviações só confundem oq poderia ser claro.

Na sua tabela de atividades vc tem um id q diz de qual tarefa aquela atividade faz parte, correto ?
Já tentou salvar a atividade ao invés da tarefa ?
[/quote]

Sim, correto. O relacionamento esta @OneToMany (Tarefa->Atividade) , bidirecional.
O problema é que, se eu salvar atividade, ela provavelmente replicara atividade no banco com o id’s diferentes ligado a mesma tarefa.
Então quando eu fosse filtrar os dados de tarefas e atividades para criar um banco, teria valores replicados com o mesmo id.

Seria dois tiros nos pés. Faço isso e o meu banco cresce exponencialmente.

O que pensei seria apenas uma relacao de objeto com o banco de dados.

Não sei se isso existe, mas talvez resolvesse.

Estou realmente perdido agora.[/quote]

Como assim ?
Oq vc está fazendo exatamente naquele momento ?
Se vc setar uma tarefa em uma atividade já existente, ele vai apenas atualizar o id da tarefa ao qual ela ta associada.
Se sua atividade não tem um id é pq ela é nova e ai vai criar uma nova atividade associada aquela tarefa.

Desculpe se entendi errado

Bom… acho que a melhor forma de você modelar isso seria da seguinte forma:

[code]@Entity
public class Tarefa {

@Id
@GeneratedValue
private Long idTarefa;

private String nomeTarefa;

private Long idAtividade; // FK referenciando ao “idAtividade” na tabela “Atividade”

//get e sets
}[/code]

[code]@Entity
public class Atividade{

@Id
@GeneratedValue  
private Long idAtividade;           //   PK como numeral é melhor

@Column(name = "NOME_ATIVIDADE")  
private String nomeAtividade;  
  
@Column(name = "TIPO")  
private String tipo;  
  
@Column(name = "PESO")  
private Double peso;  
  
@ManyToOne  
private Grupo grupo;
  
@ManyToMany  
private Set<Pessoa> pessoas= new HashSet<Pessoa>();  
  
@OneToMany  
@LazyCollection(LazyCollectionOption.FALSE)  
private Set<Fase> fases= new HashSet<Fase>();  
//gets e sets  

}[/code]

Com isso, ao salvar um projeto você usaria uma classe ProjetoDAO contendo o idTarefa. Desde modo fica mais hierárquico a estrutura.

Agora quando você for salvar, você irá fazer uma query colocando todos as atividades numa lista, depois você usará o id para “settar” na Tarefa…

Tipo assim:

 List<Atividade>listaAtividades = new ArrayList<Atividade>();
 listaAtividade = atividadeDAO.listar();    // método que retorna uma lista a partir da query "select * from atividade"
	for(Atividade a: listaAtividades){
	    listaAttividades.add(a);                     // adiciona na lista todos as atividades com suas ids
	}

Nesse ponto você tem uma lista igual seu banco, então só comparar cada atividade da lista com a descrição que você capturar da tela e usar o id dela para salvar em sua tarefa.

Aguardo retorno :stuck_out_tongue:

@MarcoAurelioBC

Como uma tarefa terá uma lista de atividades se só tem referencia a uma (private Long idAtividade) ?

É mesmo… rsrs

Você pode alterar para um array de Long, na essência vai ser a mesma coisa.
Você pode até aproveitar para usar o HashSet que não permite a inserção de valores duplicados.

[quote=fdiaz2011][quote=andrielc][quote=fdiaz2011]Como vc não se perde nessas abreviações ? :shock:
Pra mim, algumas abreviações só confundem oq poderia ser claro.

Na sua tabela de atividades vc tem um id q diz de qual tarefa aquela atividade faz parte, correto ?
Já tentou salvar a atividade ao invés da tarefa ?
[/quote]

Sim, correto. O relacionamento esta @OneToMany (Tarefa->Atividade) , bidirecional.
O problema é que, se eu salvar atividade, ela provavelmente replicara atividade no banco com o id’s diferentes ligado a mesma tarefa.
Então quando eu fosse filtrar os dados de tarefas e atividades para criar um banco, teria valores replicados com o mesmo id.

Seria dois tiros nos pés. Faço isso e o meu banco cresce exponencialmente.

O que pensei seria apenas uma relacao de objeto com o banco de dados.

Não sei se isso existe, mas talvez resolvesse.

Estou realmente perdido agora.[/quote]

Como assim ?
Oq vc está fazendo exatamente naquele momento ?
Se vc setar uma tarefa em uma atividade já existente, ele vai apenas atualizar o id da tarefa ao qual ela ta associada.
Se sua atividade não tem um id é pq ela é nova e ai vai criar uma nova atividade associada aquela tarefa.

Desculpe se entendi errado[/quote]

Não entendeu errado, eu que não pensei nisso na hora de responder, voce tem toda razão.

Certo. Vamos para o exemplo:

Projeto: A desiguinei as seguintes tarefas: D, F, G

Por padrão, Tarefa tem Atividade:
D: d_a, d_b,d_c
F: f_u,f_k,f_i
G:g_q,g_r,g_s

Escolhi para o meu Projeto A as tarefas D, F, G com essas atividades:
D: d_a, d_c
F: f_k,f_i
G:g_q

Ok, atualizo o id da minha das minhas atividades. Quando vou criar um novo Projeto B com as seguintes tarefas: D, F, G.
Logo, por ter mudado os id’s na tabela, sera apresentado as seguintes atividades para cada tarefa:
D: d_a, d_c
F: f_k,f_i
G:g_q
(isso se mudarmos o id da tarefa com as atividades 1 vez)
Se fizermos o contrario (mudar o id da atividade à tarefa), certo, vai listar certinho; entretanto se mudarmos novamente o id em outro projeto, quando eu for listar os meus projetos, com suas respectiveis tarefas e as respectivas atividades, ira listar as modificacoes referente ao ultimo projeto.

Acho q entendi, mas diga oq exatamente vc qr q aconteça.
Mas a principio me parece q oq vc precisa é de outro tipo de relacionamento entre tarefa e atividade.
Pq pelo q entendi uma atividade pode estar em mais de uma tarefa.

[quote=MarcoAurelioBC]Bom… acho que a melhor forma de você modelar isso seria da seguinte forma:

[code]@Entity
public class Tarefa {

@Id
@GeneratedValue
private Long idTarefa;

private String nomeTarefa;

private Long idAtividade; // FK referenciando ao “idAtividade” na tabela “Atividade”

//get e sets
}[/code]

[code]@Entity
public class Atividade{

@Id
@GeneratedValue  
private Long idAtividade;           //   PK como numeral é melhor

@Column(name = "NOME_ATIVIDADE")  
private String nomeAtividade;  
  
@Column(name = "TIPO")  
private String tipo;  
  
@Column(name = "PESO")  
private Double peso;  
  
@ManyToOne  
private Grupo grupo;
  
@ManyToMany  
private Set<Pessoa> pessoas= new HashSet<Pessoa>();  
  
@OneToMany  
@LazyCollection(LazyCollectionOption.FALSE)  
private Set<Fase> fases= new HashSet<Fase>();  
//gets e sets  

}[/code]

Com isso, ao salvar um projeto você usaria uma classe ProjetoDAO contendo o idTarefa. Desde modo fica mais hierárquico a estrutura.

Agora quando você for salvar, você irá fazer uma query colocando todos as atividades numa lista, depois você usará o id para “settar” na Tarefa…

Tipo assim:

 List<Atividade>listaAtividades = new ArrayList<Atividade>();
 listaAtividade = atividadeDAO.listar();    // método que retorna uma lista a partir da query "select * from atividade"
	for(Atividade a: listaAtividades){
	    listaAttividades.add(a);                     // adiciona na lista todos as atividades com suas ids
	}

Nesse ponto você tem uma lista igual seu banco, então só comparar cada atividade da lista com a descrição que você capturar da tela e usar o id dela para salvar em sua tarefa.

Aguardo retorno :stuck_out_tongue: [/quote]

Creio que se fizermos dessa forma, retorna ao caso que citei no post anterior. Vai modificar a estrutura da minha base de dados “padrão” para todos os projetos.

Caramba, esse trem esta fazendo eu coçar a cabeça; sera que modelei o meu banco de forma errada ?

[quote=fdiaz2011]Acho q entendi, mas diga oq exatamente vc qr q aconteça.
Mas a principio me parece q oq vc precisa é de outro tipo de relacionamento entre tarefa e atividade.
Pq pelo q entendi uma atividade pode estar em mais de uma tarefa.[/quote]

Não, havera sempre atividades exclusivas para uma unica tarefa.

Quero que aconteça isso:

Vou criar Projeto Colagem de Desenho

Lista todas as Tarefas: A, B, C, D, E, F, G, H, I, J, K, …,Z (querry de tarefas no banco de dados e resultado em uma JListTarefaAdicionada)

Excluo as Tarefas da JListTarefaAdicionada:
A, C, D, E, F, G, H, I, J, K, …,Z

Seleciono na minha JList de Tarefa a tarefa B

Lista as atividades de B em JListAtividadesAdicionadas: (carrego o Set do meu Objeto Tarefa selecionado na JListTarefaAdicionada)
colar, desenhar, recortar

Excluo dessa lista (apenas visualmente) a atividade recortar da tarefa B para JListTarefaExcluida.

Clico em um botao, criar projeto.

O que deve fazer:

Criar o Projeto: Colagem de Desenho com a tarefa B e atividades de B: colar, desenhar .

Se apos isso, eu criar outro projeto Colagem de Desenhos recortados, irei selecionar B então devo listar todas as atividades de B que é:
colar, desenhar, recortar

E quando eu criar esse Projeto. Terei 2 projetos:
[list]Colagem de Desenhos com a tarefa B e com atividades de B: colar, desenhar .[/list]
[list]Colagem de Desenhos Recortados com a tarefa B e com atividades de B: colar, desenhar,recortar.[/list]

Logo, quando eu for listar os meus projetos, eu possa ver também quais tarefas e atividades estao ligados a ele.

Obrigado pela atenção galera

Acredito que sim, da forma anterior fica até mais confuso de acessar os dados em suas tabelas.
Eu aconselho a mudar a base como eu falei para você não ter problemas futuros.

Estava revisando os posts aqui, e acho que dá para testar mudando só a classe e a tabela Projetos adicionando as FKs nele. O problema de se ter uma base de dados é que se for alterado algum dado avacalha tudo.

[quote=MarcoAurelioBC]Acredito que sim, da forma anterior fica até mais confuso de acessar os dados em suas tabelas.
Eu aconselho a mudar a base como eu falei para você não ter problemas futuros.

Estava revisando os posts aqui, e acho que dá para testar mudando só a classe e a tabela Projetos adicionando as FKs nele. O problema de se ter uma base de dados é que se for alterado algum dado avacalha tudo.

[/quote]

Olhe o meu novo post.

Se fosse vc, eu faria assim:

Os números são os ID´s

Atividades:
1 - colar
2 - desenhar
3 - recortar
4 - pintar
etc…

Tarefas:
1 - Colagem de Desenhos
2 - Colagem de Desenhos Recortados

Projetos:
1 - Projeto A
2 - Projeto B
3 - Projeto C

Tarefa_Atividade:
id/tarefa_id/atividade_id
1/1/1
2/1/2
3/2/1
4/2/2
5/2/3

Repare que tem a tabela Tarefa_Atividade que guarda quais atividades uma tarefa tem.
Como falei antes, o relacionamento entre tarefa e atividade deve ser ManyToMany.
Dessa forma uma atividade pode estar em várias tarefas.

Vc disse q haverá atividades exclusivas para uma tarefa.
Neste caso, vc poderá fazer isso na sua regra de negócio.

[quote=fdiaz2011]Se fosse vc, eu faria assim:

Os números são os ID´s

Atividades:
1 - colar
2 - desenhar
3 - recortar
4 - pintar
etc…

Tarefas:
1 - Colagem de Desenhos
2 - Colagem de Desenhos Recortados

Projetos:
1 - Projeto A
2 - Projeto B
3 - Projeto C

Tarefa_Atividade:
id/tarefa_id/atividade_id
1/1/1
2/1/2
3/2/1
4/2/2
5/2/3

Repare que tem a tabela Tarefa_Atividade que guarda quais atividades uma tarefa tem.
Como falei antes, o relacionamento entre tarefa e atividade deve ser ManyToMany.
Dessa forma uma atividade pode estar em várias tarefas.

Vc disse q haverá atividades exclusivas para uma tarefa.
Neste caso, vc poderá fazer isso na sua regra de negócio.[/quote]

É não fui feliz outra vez no meu exemplo.
Retomando a sua ideia com outro exemplo, creio que seja mais claro:

Atividades: (relacionamento a tarefa)
1 - Design interior do carro - 1
2 - Design banco do carro - 1
3 - Design do farol do carro - 1
4 - Calculo da energia do motor - 2
5 - Calculo da bobina do motor - 2
etc…

Tarefas:
1 - Design do carro
2 - Calculo motor

Projetos:
1 - Projeto A
2 - Projeto B

Tarefa_Atividade:
id/tarefa_id/atividade_id
1/1/1
1/2/4
1/2/5
2/1/1
2/1/2
2/1/3

É essa relação que eles tem, nunca haverá uma atividade pra varias tarefa, então não funciona o @ManyToMany. Por padrão do que estou fazendo, as Tarefas e Atividades já estão definidas assim:

Para uma tarefa A existe somente atividades específicas à A.

Obrigado mais uma vez pela atenção e ideia.

@andrielc

No seu primeiro post vc colocou

Acredito que esta acontecendo isso pela falta de referência à PK, o ideal seria se você tivesse populado a tabela com a lista inicial e sempre que fosse criar um novo projeto você referenciaria a essa PK e sempre terá sua lista padrão. Outra coisa que você pode fazer é configurar sua model já referenciando a esses dados pra não ter erro.

A sua base já tem muitos dados? não compensa mesmo remodelar?

@andrielc

Então é mais fácil ainda.
E revendo seu código…

Veja parte do seu código:

Set<Atividade> sac = mapAtividadeAdicionada.get(ta);  
ta.setAtividades(sac);

Ai vc disse: Problema se atualizo o objeto ele vai perder a lista inicial de atividades “padrão”

Mas isso é claro.
Qd vc faz ta.setAtividades(sac) vc está colocando nova lista no lugar da antiga.
Se vc quer adicionar atividades a lista antiga vc tem q fazer:

ta.getAtividades.addAll(sac);

Vc estará adicionando novas atividades à lista antiga e não colocando uma lista nova.

[quote=fdiaz2011]@andrielc

Então é mais fácil ainda.
E revendo seu código…

Veja parte do seu código:

Set<Atividade> sac = mapAtividadeAdicionada.get(ta);  
ta.setAtividades(sac);

Ai vc disse: Problema se atualizo o objeto ele vai perder a lista inicial de atividades “padrão”

Mas isso é claro.
Qd vc faz ta.setAtividades(sac) vc está colocando nova lista no lugar da antiga.
Se vc quer adicionar atividades a lista antiga vc tem q fazer:

ta.getAtividades.addAll(sac);

Vc estará adicionando novas atividades à lista antiga e não colocando uma lista nova.[/quote]

Boa, essa ai pode resolver mesmo, e a ideia de criar uma Tabela_Atividade para mapear suas tabelas também pode resolver.