Bean Validation unique Strings

Ich versuche gerade mittels BeanValidation zu verhindern, dass doppelte Einträge in die Datenbank geschrieben werden.

Ich habe folgende Klassen:


package de.fSoftware.fWarenkorb.view;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.inject.Named;
import javax.transaction.UserTransaction;

import de.fSoftware.fWarenkorb.model.Artikel2;
import de.fSoftware.fWarenkorb.repository.ArtikelRepository;

@SessionScoped
@Named
public class saveArtikelBean  implements Serializable {

	@Inject
	private ArtikelRepository artikelRepository;
	
	private Artikel2 artikel2 = new Artikel2();
	
	List<Artikel2> allArtikel = new ArrayList<Artikel2>();

	public saveArtikelBean(){
		
	}
		
	public void saveArtikel(){
		try{
			artikelRepository.saveArtikel(artikel2);
			artikel2 = new Artikel2();
		
		}
		catch(Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public Artikel2 getArtikel(){
		return this.artikel2;
		
	}
	
	public void setArtikel(Artikel2 aArtikel){
		this.artikel2 = aArtikel;
		
	}
	
	public List<Artikel2> getAllArtikel(){	
		this.allArtikel = artikelRepository.getEntriesEM();
		
		return this.allArtikel;
		
	}
}


package de.fSoftware.fWarenkorb.model;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name = "artikel2")
public class Artikel2{

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	
	@Column(unique=true, name = "artikelName")
	public String artikelName;
	
	private double ep;
	private int anzahl;

	public Long getId() {
		return id;
	}

	public void setId(Long aid) {
		this.id = aid;
		
	}
	
	public String getArtikelName(){
		return this.artikelName;
		
	}
	
	public void setArtikelName(String aArtikelName){
		this.artikelName = aArtikelName;
		
	}
	
	public double getEp(){
		return this.ep;
		
	}
	
	public void setEp(double aEp){
		this.ep = aEp;
		
	}
	
	public int getAnzahl(){
		return this.anzahl;
		
	}
	
	public void setAnzahl(int aAnzahl){
		this.anzahl = aAnzahl;
		
	}
}


package de.fSoftware.fWarenkorb.repository;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import de.fSoftware.fWarenkorb.model.Artikel;
import de.fSoftware.fWarenkorb.model.Artikel2;
import de.fSoftware.fWarenkorb.model.Bestellung;
import de.fSoftware.fWarenkorb.model.Person;
import de.fSoftware.fWarenkorb.qualifier.DataRepository;

@SessionScoped
@Named
public class ArtikelRepository  implements Serializable {

	@Inject
	@DataRepository
	private EntityManager entityManager;

	@Resource
	private UserTransaction utx;
	
	public void saveArtikel(Artikel2 e)throws NotSupportedException, SystemException  {
		
		utx.begin();
		try {
			
		entityManager.merge(e);

		flushEM();
		
		utx.commit();
	} catch (Exception ex) {
		utx.rollback();
		ex.printStackTrace();
	}
}	

	@SuppressWarnings("unchecked")
	public List<Artikel2> getEntries() {
		return entityManager.createQuery("select e from Artikel2 e")
				.getResultList();
		
	}
	
	public List<Artikel2> getEntriesEM(){
			CriteriaBuilder cb = entityManager.getCriteriaBuilder();
	        CriteriaQuery<Artikel2> criteria = cb.createQuery(Artikel2.class);
	        Root<Artikel2> entry = criteria.from(Artikel2.class);

	        criteria.select(entry).orderBy(cb.asc(entry.get("artikelName")));
	        
	        return entityManager.createQuery(criteria).getResultList();
		
	}
	
	public void flushEM(){
		entityManager.flush();
		
	}
}

Leider werden damit dennoch doppelte Einträge gespeichert.

Ich dachte ein


	@Column(unique=true, name = "artikelName")
	public String artikelName;

reichen aus, um das Attribut unique zu machen.

Unique an der Stelle sollte nur helfen wenn du über Hibernate die Datenbank erstellen lässt, du musst von Hand den Constraint erstellen

Ich dachte eigentlich, dass ich die Tabellen über Hibernate erstellen lasse.

Hier folgende Dateien:


<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
  version="2.0">
  <persistence-unit name="fWarenkorb">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:jboss/datasources/fGaestebuch</jta-data-source>
        <class>de.fSoftware.fWarenkorb.model.Artikel</class>
        <class>de.fSoftware.fWarenkorb.model.Artikel2</class>
        <class>de.fSoftware.fWarenkorb.model.BestellPosition</class>
       	<class>de.fSoftware.fWarenkorb.model.Bestellung</class>
        <class>de.fSoftware.fWarenkorb.model.Person</class>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
      <property name="eclipselink.ddl-generation" value="create-tables" />
      <property name="eclipselink.ddl-generation.output-mode" value="database" />

      <property name="hibernate.hbm2ddl.auto" value="update" />
      <property name="hibernate.id.new_generator_mappings" value="true" />
      <property name="hibernate.show_sql" value="false"></property>
    </properties>
  </persistence-unit>
</persistence>


package de.fSoftware.fWarenkorb.repository;

import javax.ejb.Stateless;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import de.fSoftware.fWarenkorb.qualifier.DataRepository;

@Stateless
public class DataRepositoryProducer {
	
	
	private EntityManager entityManager;
	
	@Produces @DataRepository @ConversationScoped
	public EntityManager getEntityManager() {
		return entityManager;
	}
	
	@PersistenceContext
	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

}

Ich verwende JPA und das ist doch eine Implementierung von Hibernate, oder?

Wie kann ich von Hand den Constraint erstellen?

dann guck doch mal in die Datenbank ob die Constraints erzeugt wurden