I have an entity Parte with a composite primary key. These are the columns:
codabast
codejerc
codparte
I have annotated my entity with #IdClass(PartePK.class). Now, to perform a query by primary key, I do this:
JPAQuery query = new JPAQuery(entityManager);
query.from(qParte).where(qParte.codabast.eq(myCodAbast)
.and(qParte.codejerc.eq(myCodEjerc)
.and(qParte.codparte.eq(myCodParte))));
Parte p = query.singleResult(qParte);
Is it needed to do it field by field? Or does exist a way to query by primary key?
I would like something like this:
PartePK primaryKey = new PartePK(3, 4, 6);
query.from(qParte).byId(primaryKey);
Thanks in advance.
Im trying to create CRUD test to show my JPA program works but it is giving me strange error when i create a new entity and commit it to the database.
The Table supplier have only one contraint and that is a unique index that is autogenerated.
i will post the classes first then what i tried to do with them
Here is the SQL for the table and contraints
-- DDL for Table SUPPLIER
CREATE TABLE SUPPLIER
( SUPPLIERID INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY,
COMPANYNAME VARCHAR(40),
CONTACTNAME VARCHAR(30),
CONTACTTITLE VARCHAR(30),
ADDRESS VARCHAR(60),
CITY VARCHAR(15),
POSTALCODE VARCHAR(10),
COUNTRY VARCHAR(15),
PHONE VARCHAR(24),
FAX VARCHAR(24)
);
-- Constraints for Table SUPPLIER
ALTER TABLE SUPPLIER ALTER SUPPLIERID NOT NULL;
ALTER TABLE SUPPLIER ALTER COMPANYNAME NOT NULL;
ALTER TABLE SUPPLIER ADD CONSTRAINT PK_SUPPLIER PRIMARY KEY (SUPPLIERID);
This is my suppliers Primary key:
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "SUPPLIERID")
private Integer supplierid;
So first i create the entity and add it to my entitymanager
Supplier sup = new Supplier("Test","Test","Test","Test","Test","Test","Test","Test","Test");
em.persist(p);
Then i save it
public void Save() {
em.getTransaction().begin();
em.getTransaction().commit();
}
And then i get the error below even thought the only constraint that can be broken is 2 identical pk but those are auto generated.
I know that my setup works because my 2 other tests ( inserting other new entities works fine).
I also close and reopen connection between each test.
[EL Warning]: 2014-09-09 17:17:33.67--UnitOfWork(1407675409)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'PK_SUPPLIER' defined on 'SUPPLIER'.
Error Code: -20001
Call: INSERT INTO SUPPLIER (ADDRESS, CITY, COMPANYNAME, CONTACTNAME, CONTACTTITLE, COUNTRY, FAX, PHONE, POSTALCODE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
bind => [9 parameters bound]
Query: InsertObjectQuery(Peristency.Supplier[ supplierid=null ])
The save method irritates me a little. Like it is written above, it performs an empty transaction, doesn't it? Shouldn't it be something like this:
public void Save() {
...
em.getTransaction().begin();
...
Supplier sup = new Supplier("Test","Test","Test","Test","Test","Test","Test","Test","Test");
em.persist(p);
...
em.getTransaction().commit();
...
}
Could it be, that the coding for the question has been shortened too much, thus scrumbling the picture? Could you provide us please with the complete coding from starting the whole transaction until committing?
I remember once a while, I had a similar problem. Main point was, that I tried to persist twice in one transaction - and that was not possible - complaining about a duplicated key problem. May be that this is a hint for your case.
Okay after alot of Wall to face action i have found the cause of my problem
If you try to commit(entitymanager.getTransaction.commit()) a entity with a null pk to the database it wont work even if the database is supposed to provide the id.
What i had to do everytime i need a new object in a state where it can be saved to the db
public void addEmployee(Employee p) {
em.getTransaction().begin();
em.persist(p);
//Doesn't have an id
System.out.println(p.getEmployeeid());
em.flush();
//now it has an id!
System.out.println(p.getEmployeeid());
em.getTransaction().commit();
}
Then later i can merge and commit at my leasure but i feel like i made a ineffecient solution with the database transaction i have.
I have created a number of entity classes from the database using the JPA.
These are the classes:
Flights
Passengers
PassengersFlights (containing primary key of passengers and flights)
Users
In the database, there are two foreign keys in the PassengersFlights table - one to Flights and one to Passengers.
The only problem I have is that the primary keys of passengers and flights are of data type Passengers and Flights in the PassengersFlights entity class. However, the data types of these in their respective entity classes are String and int, as defined in the database.
I have the following code to update the PassengersFlights table:
// Updating the Passengers_Flights table
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/flights_db", "root", "hello");
EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("Flights_AssignmentPU");
EntityManager em = emFactory.createEntityManager();
PassengersFlights booking = new PassengersFlights();
booking.setPassportNum(passport);
booking.setFlightId(flight_id);
em.getTransaction().begin();
em.persist(booking);
em.getTransaction().commit();
em.close();
}
catch (Exception e)
{
response.sendRedirect("ErrorPage.html");
}
The problem I am having is when setting the passport number and the flight id. In the project, they are defined as string and int. However, it is expecting Passenger and Flights data types. How can I solve this problem please?
If passport and flight_id are primary keys of their respectable entities, you can use getReference() to obtain a proxy object of required type with the given primary key:
booking.setPassportNum(em.getReference(Passenger.class, passport));
booking.setFlightId(em.getReference(Flight.class, flight_id));
Also note that if Passengers_Flights is just a link table without extra fields you can model the relationship between passengers and flights using #ManyToMany, without separate entity for the link table.
I am trying to retrieve data from a table which has a foreign key, "reg_no". And the foreign key is not unique, it can be duplicated.
Now I want to retrieve the data from this table using this foreign key. I will provide a "reg_no" and the Java Persistence API will retrieve a list of the result set from the table wrt to "reg_no" provided.
Please enlighten me how can I solve this problem?
You can do something like this, using JPQL:
String queryString = "SELECT t FROM YourTable t " +
"WHERE reg_no = :regNo";
Query query = getEntityManager().createQuery(queryString);
query.setParameter("regNo", regNoValue);
return query.getResultList();
EntityManager entityManager = entityManagerFactory.createEntityManager();
List results = em.createQuery("SELECT c FROM Vehicle v WHERE reg_no = :reg_no").setParameter("reg_no", new String("0000")).getResultList;
I have this issue with Hibernate that when i try to retrieve unique result using criteria hibernate returns all the content from the table.
Session session = HibernateUtil.beginTransaction();
Customer c = new Customer();
c.setCustId(custId);
Example ex = Example.create(c);
Criteria criteria = HibernateUtil.getSession().createCriteria(Customer.class);
criteria.add(ex);
Customer customer = (Customer)criteria.uniqueResult();
HibernateUtil.commitTransaction();
HibernateUtil.closeSession();
However querying the table with:
Customer customer = (Customer)session
.createSQLQuery("select * from customer_ where custid = :id")
.addEntity(Customer.class)
.setInteger("id", custId)
.uniqueResult();
returns correct entry.
custId is the table's primary key. And the Customer class contains 2 #OneToMany mappings.
Do I need to add something to the criteria example above??
The documentation says:
Version properties, identifiers and associations are ignored.
(emphasis mine)
Why not simply using Session.get() if you have the identifier?