JPA generates negative sequence values generated for ID - jpa

I am creating a CRUD web application using JPA.
Technically every thing is working fine (no errors at all), but when checking my database I noticed that the after adding a new entry to my table, the ID generated from a sequence is a negative value: -46, -45, -44, etc ...
Here are the relevant parts of my code :
My entity :
#Entity
#NamedQuery(name="Book.findAll", query="SELECT b FROM Book b")
#SequenceGenerator(name="ma_seq", sequenceName="book_seq")
public class Book implements Serializable {
private static final long serialVersionUID = 1L;
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ma_seq")
#Id private long id;
private String auteur;
private String langue;
private String titre;
public Book() {
}
//...getters and setters
}
My DAO :
public class MyDAO {
//Constructeur
public MyDAO(){
}
#PersistenceContext
private EntityManager em;
#Resource
private UserTransaction userTransaction;
public EntityManager getEm() {
return em;
}
public void setEm(EntityManager em) {
this.em = em;
}
#Transactional
public void register(Book livre) throws NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException {
// Save employee
userTransaction.begin();
this.em.persist(livre);
userTransaction.commit();
}
//other fonctions
}

after adding this to #SequenceGenerator then working fine!!!
allocationSize = 1

Related

Spring Data JPA #OneToOne mapping is not projected

This question is already phrased as an issue here: https://github.com/spring-projects/spring-data-jpa/issues/2369 but for lack of a reaction there I am copying the contents of that issue here, hoping that somebody might find what's wrong with my code or confirm that this could be a bug:
I've set up an example project here that showcases what seems to be a bug in Spring Data projections: https://github.com/joheb-mohemian/gs-accessing-data-jpa/tree/primary-key-join-column-projection-bug/complete
I have a Customer entity that has a OneToOne mapping to an Address entity:
#Entity
public class Customer {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
#OneToOne(mappedBy = "customer", cascade = CascadeType.ALL)
#PrimaryKeyJoinColumn
private Address address;
//...
}
#Entity
public class Address {
#Id
#Column(name = "customer_id")
private Long id;
#OneToOne
#MapsId
#JoinColumn(name = "customer_id")
private Customer customer;
private String street;
//...
}
Then there are simple projection interfaces:
public interface CustomerProjection {
String getFirstName();
String getLastName();
AddressProjection getAddress();
}
public interface AddressProjection {
String getStreet();
}
But when I try to fetch a projected entity from a repository method like this one:
public interface CustomerRepository extends CrudRepository<Customer, Long> {
//...
<T> T findById(long id, Class<T> type);
}
, getAddress() on the projection will be null, whereas getAddress() when fetching the entity type is populated correctly. Of these two unit tests, only testEntityWithOneToOne()will be successful:
#BeforeEach
void setUpData() {
customer = new Customer("first", "last");
Address address = new Address(customer, "street");
customer.setAddress(address);
entityManager.persist(address);
entityManager.persist(customer);
}
#Test
void testEntityWithOneToOne() {
Customer customerEntity = customers.findById(customer.getId().longValue());
assertThat(customerEntity.getAddress()).isNotNull();
}
#Test
void testProjectionWithOneToOne() {
CustomerProjection customerProjection = customers.findById(customer.getId(), CustomerProjection.class);
assertThat(customerProjection.getAddress()).isNotNull();
}
What's the problem here?

#Transactional in spring JPA

I have a spring boot application where I need to update a migratedCustomer db table based on userId and phoneNumber.
Since I have to use for loop in the service layer for every update, it is creating a
new transaction and performance is hampered.
how could I make sure only one transaction is created and hence to improve the performance. code is like below
#Entity
#Table(name = "MigratedCustomer")
public class MigratedCustomer {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String userId;
private String phoneNumber;
#Temporal(TemporalType.TIMESTAMP)
private Date createdTimestamp;
private int batchNumber;
private String comment;
}
public class MigratedCustomerService {
#Autowired
private UserRepository userRepository;
public void updateMsisdn(List<MigratedCustomer> savedCustomers) {
for (MigratedCustomer savedCustomer : savedCustomers) {
userRepository.updateStatus(savedCustomer.getUserId(),
savedCustomer.getPhoneNumber());
}
}
}
public interface MsisdnRepository extends JpaRepository<Msisdn, Long> {
#Modifying
#Query(value = "UPDATE Msisdn SET status=INACTIVE where userId=:userId and phoneNumber=:phoneNumber",
nativeQuery = true)
void updateStatus(#Param("userId") String userId, #Param("phoneNumber") String phoneNumber);
}

Could not create stateless EJB with JPA

I'm trying to insert some data to DB with EJB and JPA. When I execute the code i got the serverError: class javax.faces.el.EvaluationException javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB error. Here my code. I have try lot of by changing various things. what is that error occurred? I think my Entity manager initialization has some wrong
DesignationEntity de = new DesignationEntity();
de.setDesignationName(this.designationName);
de.setDesignationDescription(this.designationDescription);
ds.addDesignationDb(de);
EJB service class
#Stateless
#LocalBean
public class DesignationService {
#PersistenceUnit(unitName = "ecs2complainmanager")
private EntityManager em;
public DesignationService() {
}
public void addDesignationDb(DesignationEntity de){
em.persist(de);
}
}
Entity class
#Entity
public class DesignationEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Integer designationId;
private String designationName;
private String designationDescription;
#OneToOne(mappedBy = "designationId")
private UserEntity user;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getDesignationId() {
return designationId;
}
public void setDesignationId(Integer designationId) {
this.designationId = designationId;
}
public String getDesignationName() {
return designationName;
}
public void setDesignationName(String designationName) {
this.designationName = designationName;
}
public String getDesignationDescription() {
return designationDescription;
}
public void setDesignationDescription(String designationDescription) {
this.designationDescription = designationDescription;
}
public UserEntity getUser() {
return user;
}
public void setUser(UserEntity user) {
this.user = user;
}
}
#PersistenceUnit is the cause. After I changed it to #PersistenceContext

JPA One-to-Many relationship using a List - OrderBy ignored/not working

I'll try to formulate the question more simple:
#Entity
public class One implements Serializable {
...
#Id
#GeneratedValue
private Long id;
#OneToMany
#OrderBy("name ASC")
private List<Many> many;
...
First I populate the List with some Many-Entities and persist the One-Entity. Second I retrieve (em.find) the One-Entity expecting the List in ascending order by Many#name, but it's not ordered by name. The List is ordered by id. Complete code see below if necessary.
Original post some days ago:
I'm using a current Netbeans Glassfish bundle.
Product Version: NetBeans IDE 8.0 (Build 201403101706)
Updates: NetBeans IDE is updated to version NetBeans 8.0 Patch 2
Java: 1.7.0_51; Java HotSpot(TM) 64-Bit Server VM 24.51-b03
Runtime: Java(TM) SE Runtime Environment 1.7.0_51-b13
System: Mac OS X version 10.9.3 running on x86_64; UTF-8; de_DE (nb)
The JPA #OrderBy annotation is completely ignored.
#Entity
public class One implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long id;
#OneToMany
#OrderBy("name ASC")
private List<Many> many;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<Many> getMany() {
return many;
}
public void setMany(List<Many> many) {
this.many = many;
}
}
The many Entity
#Entity
public class Many implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long id;
private String name;
public Many() {
}
public Many(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The service class (EJB)
#Stateless
public class Service {
#PersistenceContext(unitName = "cwPU")
private EntityManager em;
public One createOne() {
return em.merge(new One());
}
public Many createMany(String name) {
return em.merge(new Many(name));
}
public One add(Long oneId, Long manyId) {
One one = em.find(One.class, oneId);
Many many = em.find(Many.class, manyId);
one.getMany().add(many);
return one;
}
public One find(Long id) {
One one = em.find(One.class, id);
return one;
}
}
The main class
public class Main {
public static void main(String[] args) throws NamingException {
EJBContainer container = EJBContainer.createEJBContainer();
Context ctx = container.getContext();
Service service = (Service) ctx.lookup("java:global/classes/Service");
One one = service.createOne();
Many many = service.createMany("the-first");
service.add(one.getId(), many.getId());
many = service.createMany("a-second");
one = service.add(one.getId(), many.getId());
one = service.find(one.getId());
System.out.println("-------------------------------------------------");
for (Many m : one.getMany()) {
System.out.println(m.getName());
}
container.close();
}
}
The output:
the-first
a-second
No matter what I write to the #OrderBy annotation (name ASC, name DESC, id ASC, id DESC), the output is always the same ascending order by the id.
Any idea what I'm missing?
The #Orderby annotation doesn't actually work that way. According to the javadoc, the annotation "Specifies the ordering of the elements of a collection ...at the point when the collection is retrieved."
So the annotation affects the result of the query (find), but does not dictate the order in the collection you store the result set into.
The solution is calling em.refresh (at the right place) as stated from Chris and WPrecht. I had to do this in a separate EJB method.
This did not work:
public One find(Long id) {
em.refresh(em.find(One.class, id)); // did not work
One one = em.find(One.class, id);
return one;
}
Adding a separate refresh method
public void refresh(Long id) {
em.refresh(em.find(One.class, id));
}
and calling it in the main program
...
service.refresh(one.getId());
one = service.find(one.getId());
...
works!
Probably I have to do more reading to understand caching.

Why entityManager.contains returns different results?

This is in JPA2 (EclipseLink) and JSF2.
I have an entity class Student:
#Entity
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstname;
private String lastname;
private int age;
public Student(String firstname, String lastname, int age) {
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
}
public Student() {
}
// accessors and mutators here
}
Session bean StudentFacade that inherits AbstractFacade:
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public T edit(T entity) {
return getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
// other methods: findAll, findRange, count
}
#Stateless
public class StudentFacade extends AbstractFacade<Student> {
#PersistenceContext(unitName = "jpa2testsPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public StudentFacade() {
super(Student.class);
}
public boolean contains(Student s) {
return getEntityManager().contains(s);
}
public void testContains() {
Student s = find(1L);
boolean isContains = getEntityManager().contains(s);
}
}
This is my JSF Managed Bean:
#ManagedBean
#RequestScoped
public class IndexController {
#EJB
private StudentFacade studentFacade;
/**
* Creates a new instance of IndexController
*/
public IndexController() {
}
public String test() {
Student s = new Student("John", "Doe", 20);
studentFacade.create(s);
Student s1 = studentFacade.find(1L); // This works because table only has 1 record
boolean isContains = studentFacade.contains(s);
return null;
}
}
When I run test() from managed bean, isContains is false. But when testContains() in StudentFacade is called, isContains is true. Why is this?
StudentFacade is a Stateless Session Bean (SSB). The contents of its instance variables are not guaranteed to be preserved across method calls (reference). It's like having a different instance of EntityManager created for each method invocation.
When you run your test from the managed bean, you invoke two different methods on the SSB, therefore a different EntityManager instance is created for each call, and the second one does not contain the Student instance because it has not been loaded yet.
But when you run your test inside a method of the SSB itself, the same EntityManager is used for the scope of the entire method, therefore the call to contains() returns true.