0

Is it even possible to use generics with genericPersist and isUniqueEntity? The persist method seems fairly straightforward:

package net.bounceme.dur.usenet.driver;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.Folder;
import javax.mail.Message;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import net.bounceme.dur.usenet.model.Article;
import net.bounceme.dur.usenet.model.Newsgroup;
import net.bounceme.dur.usenet.model.Usenet;

public class Main {

    private static final Logger LOG = Logger.getLogger(Main.class.getName());
    private Usenet u = Usenet.INSTANCE;

    public static void main(String[] args) {
        try {
            Main main = new Main();
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Main() throws Exception {
        EntityManagerFactory emf;
        EntityManager em;
        emf = Persistence.createEntityManagerFactory("USENETPU");
        List<Newsgroup> subscribed = getFolders();
        em = emf.createEntityManager();
        for (Newsgroup newsgroup : subscribed) {
            persistNewsgroups(em, newsgroup);
            List<Message> messages = u.getMessages(newsgroup.getNewsgroup());
            LOG.fine(newsgroup + "  " + messages.size() + " messages");
            for (Message message : messages) {
                LOG.fine("message " + message.getMessageNumber());
                Article article = new Article(message);
                persistArticle(em, article);
            }
        }
        em.close();
    }

    private boolean isUniqueArticle(Article article, List<Article> articles) {
        LOG.fine(articles.toString());
        for (Article a : articles) {
            if (a.getSubject().equalsIgnoreCase(article.getSubject())) {
                return false;
            }
        }
        LOG.fine("new\t\t" + article);
        return true;
    }

    private void persistArticle(EntityManager em, Article article) {
        LOG.fine(article.toString());
        TypedQuery<Article> query = em.createQuery("SELECT a FROM Article a", Article.class);
        List<Article> results = query.getResultList();
        if (isUniqueArticle(article, results)) {
            em.getTransaction().begin();
            em.persist(article);
            em.getTransaction().commit();
        }
    }

    private <T> void genericPersist(EntityManager em, Class<T> entity, String queryString) {
        TypedQuery<T> query = em.createQuery(queryString, entity);
        List<T> results = query.getResultList();
        if (isUniqueEntity(entity, results)) {
            em.getTransaction().begin();
            em.persist(entity);
            em.getTransaction().commit();
        }
    }

    private <T> boolean isUniqueEntity(Class<T> entity,List<T> results) {
        return false;
    }

    private void persistNewsgroups(EntityManager em, Newsgroup newNewsgroup) {
        LOG.fine(newNewsgroup.toString());
        TypedQuery<Newsgroup> query = em.createQuery("SELECT n FROM Newsgroup n", Newsgroup.class);
        List<Newsgroup> results = query.getResultList();
        if (isUniqueNewsgroup(newNewsgroup, results)) {
            em.getTransaction().begin();
            em.persist(newNewsgroup);
            em.getTransaction().commit();
        }
    }

    private boolean isUniqueNewsgroup(Newsgroup newNewsgroup, Iterable<Newsgroup> results) {
        LOG.fine(results.toString());
        for (Newsgroup existingNewsgroup : results) {
            if ((existingNewsgroup.getNewsgroup().equals(newNewsgroup.getNewsgroup()))) {
                return false;
            }
        }
        LOG.fine(newNewsgroup + "\tnew");
        return true;
    }

    private List<Newsgroup> getFolders() {
        List<Folder> folders = u.getFolders();
        List<Newsgroup> newsgroups = new ArrayList<>();
        for (Folder folder : folders) {
            Newsgroup newsgroup = new Newsgroup(folder);
            newsgroups.add(newsgroup);
        }
        LOG.fine(newsgroups.toString());
        return newsgroups;
    }
}

For the isUniqueEntity all I can think of is to determine the type of the object and then use a switch, but that doesn't seem much of a savings. How can this be done?

Assuming that the entity has a single @Unique field, determine that field and then query the database accordingly?

Thufir
  • 8,216
  • 28
  • 125
  • 273

1 Answers1

1

Hm I'm not quite sure - are you trying to replace isUniqueArticle and isUniqueNewsgroup with isUniqueEntity? Can you add something to Article/NewsGroup? If you can add an interface to them and a method to each then yes. If you cannot then probably you can also do it but I can't think of that way :)

Anyway you can try this. Add an interface to both classes:

public interface Equalable<T> {
    boolean isEqual(T other);
}

private <T extends Equalable> boolean isUniqueEntity(T entity, Iterable<T> results) {
    LOG.fine(results.toString());
    for (T resultEntity : results) {
        if (resultEntity.isEqual(entity))) {
            return false;
        }
    }
    LOG.fine(newNewsgroup + "\tnew");
    return true;
}

Then implement isEqual(T other) in both classes (just copy paste the condition you have in your "ifs" in both isXUnique now).

If that is what you were looking for and works (haven't compiled it!) the persist method should be no problem for you :)

Mateusz Dymczyk
  • 14,969
  • 10
  • 59
  • 94