Nos bancos de dados relacionais, “todas” as tabelas devem ter a coluna id. A chave primaria é obrigatório, não tem jeito. Isso é para uma melhor pratica de estrutura de dados. Leia este post depois [JPA] Tabelas sem chave primária.
No seu caso, se cada empresa pode ter mais de uma atividade, então você pode ‘inverter a referencia’. Como os id são obrigatório, você cria uma coluna na tabela empresa chamada idAtividade e coloca id da atividade desejada. Com isso, você pode ter duas ou muito mais empresas, em que no campo idAtividade, esta o id 25 (que se refere a atividade 25). É claro, de alguma forma você tem que referenciar na sua aplicação. Tipo, antes de salvar a atividade, você já tem que ter identificado a empresa. Isso são coisas comuns que envolve algumas técnicas e praticas de programação. Eu por exemplo, colocaria o id da empresa na sessão de um pagina que esta logada. Pois assim, ao salvar uma nova atividade, eu já referencio o numero do id da atividade nas empresas que tem o id da sessão. Se for mais de uma empresa, então não se pode usar sessão, logo você terá que buscar todos os ids referentes e criar uma lista para persistir no banco. Igual como se estivesse identificando uma lista de emails ou contas de amigos no facebook.
Só dois detalhes, se uma atividade pode se referenciar a mais de uma empresa e uma empresa pode ter varias atividades, então você precisa de no minimo três tabelas para isso, com apenas três campos: idTabela que é obrigatório, mais a coluna idEmpresa, e outra coluna referente ao idAtividade relacionada.
E outro detalhe, é que nesse caso você tem que identificar o id da atividade antes de salva-lo no banco, ou seja, o id da tabela atividade deve ser gerado na aplicação. Uma solução concatenar toda uma data(o próprio facebook faz isso). ano+mês+dia+hora+minutos+segundos+milisegundos ou então só
Long idAtividade1=new Date().getTime() // ou
Long idAtividade2=System.currentTimeMillis();
Das duas formas o valor nunca vai se repetir. A menos que sejam executados no momento de milisegundos exatos. Mas para evitar isso concatena um numero sorteado entre 1 e 10 mil. Veja um exemplo para dois ids executados quase no mesmo instante e como eles pode ser salvos no banco:
public static void main(String[] args) {
long t1=System.currentTimeMillis();
long t2=System.currentTimeMillis();
System.out.println(t1);
System.out.println(t2);
int valor1=(int)(Math.random()*10000+10000);
int valor2=(int)(Math.random()*10000+10000);
Long idAtividade1=Long.parseLong(new Date().getTime()+""+valor1);
Long idAtividade2=Long.parseLong(new Date().getTime()+""+valor2);
System.out.println("valor1: "+valor1);
System.out.println("valor2: "+valor2);
System.out.println("idAtividade1: "+idAtividade1);
System.out.println("idAtividade2: "+idAtividade2);
}
Inicialmente parece complicado e desvantajoso, mas isso é o que o banco faria se você usasse relacionamentos diretos(@OneToMany, etc…), com a diferença que teria uma estrutura diretamente vinculada a outra, o que complica diversas operações nos bancos, além de deixa-lo lento com tantas tabelas ‘ligadas’ as outras.
Bom faça seus próprios testes e tire suas próprias conclusões.