Question

I try to gather statistics of visitors for two services. It consists of daily visitors statistics and overall record. Each service can be accessed by different names. For example, user, admin, support etc. Each will have its own record as own statistics.

Here is my DB structure:

service_one: id, name

service_two: id, name

daily_stats: id, date, service_one_id, service_one_visitors, service_two_id, service_two_visitors, overall_visitors

record_stats: id, service_one_id, service_one_record, service_one_record_date, service_two_id, service_two_record, service_two_record_date

Here are the relations between tables:

service_one --- (one to many) ---> daily_stats(service_one_id)

service_one --- (one to many) ---> record_stats(service_one_id)

service_two --- (one to many) ---> daily_stats(service_two_id)

service_two --- (one to many) ---> record_stats(service_two_id)

Mapping for service_one (the same is for service_two). Also setters were omitted in order to shorten the example:

@Entity
@Table(name = "service_one")
public class ServiceOne implements Serializable {
    private int id;
    private String name;

    private Set<RecordStats> recordStats = new HashSet<RecordStats>(0);
    private Set<DailyStats> dailyStats = new HashSet<DailyStats>(0);

    public ServiceOne() {}

    public ServiceOne(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", nullable = false, unique = true)
    public int getId() {
        return id;
    }

    @Column(name = "name")
    public String getName() {
        return name;
    }

    @OneToMany(fetch = LAZY, mappedBy = "service_one_id")
    public Set<RecordStats> getRecordStats() {
        return recordStats;
    }

    @OneToMany(fetch = LAZY, mappedBy = "service_one_id")
    public Set<DailyStats> getDailyStats() {
        return dailyStats;
    }
}

daily_stats mapping:

@Entity
@Table(name = "daily_stats", uniqueConstraints = {
        @UniqueConstraint(columnNames = "date")
})
public class DailyStats implements Serializable{

    private int id;
    private Date date;
    private ServiceOne service_one_id;
    private int service_one_visitors;
    private ServiceTwo service_two_id;
    private int service_two_visitors;
    private int overall_visitors;

    public DailyStats() {}

    public DailyStats(DailyStats rec) {
        this.id = rec.getId();
        //...
    }

    @Id
    @GeneratedValue
    @Column(name = "id", nullable = false)
    public int getId() {
        return id;
    }

    @Temporal(DATE)
    @Column(name = "date")
    public Date getDate() {
        return date;
    }

    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "id", nullable = false)
    public ServiceOne getService_one_id() {
        return service_one_id;
    }

    @Column(name = "service_one_visitors")
    public int getService_one_visitors() {
        return service_one_visitors;
    }

    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "id", nullable = false)
    public ServiceTwo getService_two_id() {
        return service_two_id;
    }

    @Column(name = "service_two_visitors")
    public int getService_two_visitors() {
        return service_two_visitors;
    }

    @Column(name = "overall_visitors")
    public int getOverall_visitors() {
        return overall_visitors;
    }
}

record_stats mapping:

@Entity
@Table(name = "record_stats", uniqueConstraints = {
        @UniqueConstraint(columnNames = "service_one_record_date"),
        @UniqueConstraint(columnNames = "service_two_record_date")
})
public class RecordStats implements Serializable {

    private int id;
    private ServiceOne service_one_id;
    private int service_one_record;
    private Date service_one_rec_date;
    private ServiceTwo service_two_id;
    private int service_two_record;
    private Date service_two_rec_date;

    public RecordStats() {}

    public RecordStats(RecordStats rec) {
        this.id = rec.getId();
        //...
    }

    @Id
    @GeneratedValue
    @Column(name = "id", nullable = false)
    public int getId() {
        return id;
    }

    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "id", nullable = false)
    public ServiceOne getService_one_id() {
        return service_one_id;
    }

    @Column(name = "service_one_record")
    public int getService_one_record() {
        return service_one_record;
    }

    @Column(name = "service_one_record_date")
    @Temporal(DATE)
    public Date getService_one_rec_date() {
        return service_one_rec_date;
    }

    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "id", nullable = false)
    public ServiceTwo getService_two_id() {
        return service_two_id;
    }

    @Column(name = "service_two_record")
    public int getService_two_record() {
        return service_two_record;
    }

    @Column(name = "service_two_record_date")
    @Temporal(DATE)
    public Date getService_two_rec_date() {
        return service_two_rec_date;
    }
}

Trying to create new entry throws exception:

public static void main(String[] args) {
    ServiceOne serviceOne = new ServiceOne();
    serviceOne.setName("test");

    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
    Session session = sessionFactory.openSession();

    session.beginTransaction();
    session.save(serviceOne);
    session.getTransaction().commit();

    //get records
    session = sessionFactory.openSession();
    session.beginTransaction();
    List result = session.createQuery("from service_one").list();
    for (ServiceOne o : (List<ServiceOne>)result) {
        System.out.println(o.getName());
    }
    session.getTransaction().commit();

    session.close();
}

org.hibernate.MappingException: Repeated column in mapping for entity: VisitorsCounter.model.entity.DailyStats column: id (should be mapped with insert="false" update="false")

What is wrong with my mapping?

Was it helpful?

Solution

It seems to me that

@JoinColumn(name = "id", nullable = false)
public ServiceOne getService_one_id() {
    return service_one_id;
}

in DailyStats is wrong; you should have name = "service_one_id".

You have the same problem in getService_two_id() and in methods of same names in RecordStats.

May I also ask why don't you name the references in the classes fields serviceOne and serviceTwo instead of service_one_id and service_two_id.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top