2016-09-08 3 views
0

Этот код сохраняется в компании, у которой есть HashSet Activity.JPA 2.1 спящий синхронный переход с одного на другого с двоичным кодом

em.getTransaction().begin(); 

// De Morgen. 
MediaGroup mediaGroupDM = new MediaGroup("De Persgroep", "Christian van Thillo", "Van Thillo Family"); 
HashSet<Activity> activities = new HashSet<>(); 
activities.add(new Activity("News paper")); 
activities.add(new Activity("News website")); 
activities.add(new Activity("Facebook opinion")); 
Company deMorgen = new Company("De Morgen", "http://www.demorgen.be/", mediaGroupDM, activities); 
em.persist(deMorgen); 

em.getTransaction().commit(); 

Результат в базе данных в порядке. Создается новая таблица «company_activities» с идентификатором деятельности компании и id, как показано ниже.

Result in the DB

Но когда я добавить еще одну компанию, которая имеет те же действия, это исключения брошено: MySQLIntegrityConstraintViolationException: Дублирование запись «3» для ключа «UK_9j7c1qdg3rnhjioqut33ki7pr»

Я понимаю, что он не хочет дубликаты в колонке activities_id но то, что я пытаюсь достичь это:

 
Company_id | activities_id 
-----------|-------------- 
1   | 3 
1   | 4 
1   | 5 
2   | 3 
2   | 4 
2   | 5 

субъект компании

@Entity 
public class Company{ 
    @Id 
    @GeneratedValue 
    private long id; 
    @Column(unique = true) 
    private String name; 
    private String frontPageUrl; 
    private String domainUrl; 
    @OneToOne(cascade = CascadeType.ALL) 
    private MediaGroup mediaGroup; 
    @OneToMany(cascade = CascadeType.ALL) 
    private Set<Activity> activities = new HashSet<>(0); 

Деятельность объект

@Entity 
public class Activity { 
    @Id 
    @GeneratedValue 
    private long id; 
    @Column(unique = true) 
    private String name; 
    private String description; 

Я попытался довольно некоторые конфигурации с аннотациями. Я также получил активность из базы данных и добавил их к свойствам новой компании, но не повезло.

Код испытания Main:

public class Main { 

    public Main() { 
    } 

    public static void main(String[] args) { 
     EntityManagerFactory emf = Persistence.createEntityManagerFactory("MediaObserver"); 
     EntityManager em = emf.createEntityManager(); 

     Seed.companies(em); 

     //emf.close(); 
    } 
} 

Код испытания Seed:

public class Seed { 

    public static void companies(EntityManager em) { 
     init(em); 
     //reuseActivities(em); 
    } 

    private static void reuseActivities(EntityManager em) { 
     em.getTransaction().begin(); 

     Company standaard = selectCompanyByName(em, "De Standaard"); 
     Activity facebook = selectActivityByName(em, "Facebook opinion"); 
     Activity newsWebsite = selectActivityByName(em, "News website"); 
     standaard.getActivities().add(facebook); 
     standaard.getActivities().add(newsWebsite); 
     em.persist(standaard); 

     em.getTransaction().commit(); 
    } 

    private static void init(EntityManager em) { 
     em.getTransaction().begin(); 

     // De Morgen. 
     MediaGroup mediaGroupDM = new MediaGroup("De Persgroep", "Christian van Thillo", "Van Thillo Family"); 
     HashSet<Activity> activities = new HashSet<>(); 
     activities.add(new Activity("News paper")); 
     activities.add(new Activity("News website")); 
     activities.add(new Activity("Facebook opinion")); 
     Company deMorgen = new Company("De Morgen", "http://www.demorgen.be/", mediaGroupDM, activities); 
     em.persist(deMorgen); 

     // Standaard. 
     MediaGroup mediaGroupDS = new MediaGroup("Mediahuis", "Gert Ysebaert", ""); 
     Company standaard = new Company("De Standaard", "http://www.standaard.be/", mediaGroupDS); 
     em.persist(standaard); 

     em.getTransaction().commit(); 
    } 

    private static Company selectCompanyByName(EntityManager em, String companyName) { 
     Query query = em.createQuery("SELECT c FROM Company c " + 
       "WHERE c.name = :name"); 
     query.setParameter("name", companyName); 

     return (Company) query.getSingleResult(); 
    } 

    private static Activity selectActivityByName(EntityManager em, String activityName) { 
     Query query = em.createQuery("SELECT a FROM Activity a " + 
       "WHERE a.name = :name"); 
     query.setParameter("name", activityName); 

     try { 
      return (Activity) query.getSingleResult(); 
     } catch (NoResultException e) { 
      System.out.println(activityName + " not found"); 
      return null; 
     } 
    } 
} 
+0

Вопрос в том, что вы хотите повторно использовать все виды деятельности для новой компании? –

+0

Да, я считаю, что это нормализованный способ обойти это. – progonkpa

+0

Приложите все свои тестовые коды. –

ответ

1

То, что вы здесь многие-ко-многим, а не @OneToMany, как вы заявили в вашем Company сущности. Старайтесь его определить как:

@ManyToMany(cascade = CascadeType.ALL) 
@JoinTable(name = "company_activity", 
    joinColumns = {@JoinColumn(name = "company_id")}, 
    inverseJoinColumns = {@JoinColumn(name = "activity_id")}) 
private Set<Activity> activities = new HashSet<>(0); 
+0

Вы правы, это сработало! Я лучше прочитаю некоторые о типах отношений :) – progonkpa