Results 1 to 4 of 4
  1. #1
    s3ib is offline Member
    Join Date
    Dec 2010
    Posts
    18
    Rep Power
    0

    Default Hibernate - Problem with manytomany mapping

    Application is a TV guide. There are two Entity classes - TVChannel and TVProgram and I have many to many mapping between them because the same program can run on multiple channels on different times and even on the same channel on different times. I can attach a TVProgram to multiple channels but problem comes when I'm attaching different startingtimes for each relation.

    I'll post my code here.

    TVChannel.java:
    Java Code:
    //imports...
    @Entity
    @Table(name="TV_CHANNELS")
    public class TVChannel implements Serializable{
    	
    	private Long id;
    	private String name;
    	private String description;
    	private List<TVProgram> programs = new ArrayList<TVProgram>();
    
    	@Id
    	@GeneratedValue
    	@Column(name="C_ID",nullable=false)
    	public Long getId() {
    		return id;
    	}
    	
    	public void setId(Long id) {
    		this.id = id;
    	}
    	
    	@Column(name="C_NAME",nullable=false)
    	public String getName() {
    		return name;
    	}
    	
    	public void setName(String name) {
    		this.name = name;
    	}
    	
    	@Column(name="C_DESCRIPTION")
    	public String getDescription() {
    		return description;
    	}
    	
    	public void setDescription(String description) {
    		this.description = description;
    	}
    	
    	@Column(name="C_RELATED_PROGRAMS")
    	@ManyToMany
    	@JoinTable(name="JOIN_CHANNELS_PROGRAMS", joinColumns={@JoinColumn(name="C_ID",
    			 referencedColumnName="C_ID")},
    			inverseJoinColumns={@JoinColumn(name="P_ID",  referencedColumnName="P_ID"),
    			@JoinColumn(name="START_TIME", referencedColumnName="P_START_TIME")
    	})
    	public List<TVProgram> getPrograms() {
    		return programs;
    	}
    
    	public void setPrograms(List<TVProgram> programs) {
    		this.programs = programs;
    	}
    	
    }
    TVProgram.java
    Java Code:
    //...imports
    
    @Entity
    @Table(name="TV_PROGRAMS")
    public class TVProgram implements Serializable{
    	
    	private Long id;
    	private String name;
    	private String genre;
    	private Date startingTime;
    	private int duration; // minutes
    	private List<TVChannel> channels = new ArrayList<TVChannel>();
    
    	@Id
    	@GeneratedValue
    	@Column(name="P_ID",nullable=false)
    	public Long getId() {
    		return id;
    	}
    	
    	public void setId(Long id) {
    		this.id = id;
    	}
    	
    	@Column(name="P_NAME")
    	public String getName() {
    		return name;
    	}
    	
    	public void setName(String name) {
    		this.name = name;
    	}
    	
    	@Column(name="P_GENRE")
    	public String getGenre() {
    		return genre;
    	}
    	
    	public void setGenre(String genre) {
    		this.genre = genre;
    	}
    	
    	@Column(name="P_START_TIME",nullable=false)
    	public Date getStartingTime() {
    		return startingTime;
    	}
    	
    	public void setStartingTime(Date startingTime) {
    		this.startingTime = startingTime;
    	}
    	
    	@Column(name="P_DURATION",nullable=false)
    	public int getDuration() {
    		return duration;
    	}
    	
    	public void setDuration(int duration) {
    		this.duration = duration;
    	}
    	
    	@Column(name="P_RELATED_CHANNELS")
    	@ManyToMany
    	@JoinTable(name="JOIN_CHANNELS_PROGRAMS", 
    			joinColumns={
    				@JoinColumn(name="P_ID", referencedColumnName="P_ID"),
    				@JoinColumn(name="START_TIME", referencedColumnName="P_START_TIME")
    			},
    			inverseJoinColumns={@JoinColumn(name="C_ID", referencedColumnName="C_ID")}
    	)
    	public List<TVChannel> getChannels() {
    		return channels;
    	}
    
    	public void setChannels(List<TVChannel> channels) {
    		this.channels = channels;
    	}
    	
    }
    Main.java-s main method
    Java Code:
    		
    		Configuration config = new Configuration();
    		config.addAnnotatedClass(TVChannel.class);
    		config.addAnnotatedClass(TVProgram.class);
    		config.configure("hibernate.cfg.xml");
    		new SchemaExport(config).create(true, true);
    
    		
    		SessionFactory sessionFactory = config.buildSessionFactory();
    		Session session = sessionFactory.getCurrentSession();
    		
    		session.beginTransaction();
    		
    		/* **************************
    		 * ******* TEST DATA ********
    		 * **************************/
    		
    		TVChannel channel1 = new TVChannel();
    		channel1.setName("Channel 1");
    		channel1.setDescription("Bla bla bla.");
    		
    		TVChannel channel2 = new TVChannel();
    		channel2.setName("Channel 2");
    		channel2.setDescription("Bla-bla-bla");
                    
                    TVProgram show1 = new TVProgram();
                    show1.setName("The Cool Show");
                    show1.setDuration(60);
                    show1.setGenre("Fiction");
    
    
                    show1.setStartingTime(parseDate("01/08/2011 7:00"));
    		channel1.getPrograms().add(show1);
    		session.save(show1);
    		session.save(channel1);
    
                    //And now let's set the same show on the same channel but on a different time
    		show1.setStartingTime(parseDate("01/08/2011 15:00"));
    		channel1.getPrograms().add(show1);
    
                    //and let's add it on a second channel too for the same time
    		channel2.getPrograms().add(show1);
    		session.save(show1);
                    session.save(channel1);
    		session.save(channel2);
    		
    		session.getTransaction().commit();
    When i now log in to my postgres admin and check for the table that keeps joining relations i see:
    C_ID P_ID START_TIME
    1 2 01/08/2011 15:00
    1 2 01/08/2011 15:00
    3 2 01/08/2011 15:00

    But what I wantet to see was:
    C_ID P_ID START_TIME
    1 2 01/08/2011 7:00
    1 2 01/08/2011 15:00
    3 2 01/08/2011 15:00



    I'm really new to hibernate so i appologise if the question is stupid :/

  2. #2
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,172
    Rep Power
    20

    Default

    I think you're missing an element from your model.
    You have a TV program, and a TV channel...but since this is a TV Guide, then the thing mapping the two together is a program guide entry.
    That would be similar to your join table, except now you can drop the attempt at many-to-many, and simply have a one-to-many for program to entry, and channel to entry.
    Obviously your many-to-many should work, but in this case I would argue it shouldn't even be needed as the model currently doesn't reflect what you're modelling.

  3. #3
    s3ib is offline Member
    Join Date
    Dec 2010
    Posts
    18
    Rep Power
    0

    Default

    I dont really get what you mean. How can I make a OneToMany relationship between TVProgram and TVChannel. You mean one TVProgram is related to many TVChannels?


    Java Code:
    show1.setStartingTime(parseDate("01/08/2011 7:00"));
    channel1.setProgram(show1);
    session.save(show1);
    session.save(channel1);
    		
    //now let's set a time for a re-run of the show on two different channels
    show1.setStartingTime(parseDate("01/08/2011 15:00"));
    channel1.setProgram(show1);
    channel2.setProgram(show1);
    session.save(show1);
    session.save(channel1);
    session.save(channel2);
    It saves only on line in TVProgram and two lines on channels.
    But what I needed was three TV programs, with the same primary key but with different times and foreign channel keys.

    And that model really seems odd too for what I'm doing.

    The other way around. One TVChannel to Many Programs. I also cant see how can I accomplish what I want with this model. Ok I can have one show on different times, but i can't have it on different channels that way.
    I think I still need a third table for relations, where there is 3 columns: Program_id, Channel_id, starting time and the only model that can give this to me is ManyToMany. Problems is I still don't know how to make a relation between a channel and program and later make the exact same relation of primary key-s but with a different timestamp.

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,172
    Rep Power
    20

    Default

    Java Code:
    TVProgram (1) - (*) TVGuideEntry (*) - (1) TVChannel
    The TVGuideEntry holds a reference to the program and the channel and the time (that's the extra piece of info) it is on.
    So your model needs the bit in the middle. That way you can avoid trying to map program to channel directly.

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 11:04 PM
  2. [newbie] Hibernate one-to-one mapping
    By megabyte in forum JDBC
    Replies: 1
    Last Post: 04-07-2011, 06:10 AM
  3. problem with ejb 3.0 entity beans with manyToMany relationship
    By makcro in forum Enterprise JavaBeans (EJB)
    Replies: 0
    Last Post: 07-26-2007, 08:37 PM
  4. Replies: 1
    Last Post: 07-06-2007, 07:27 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •