โŒ

Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

Select parent and only some fields from child in @OneToMany relationships using JPA and Criteria Builder

Implemented one to many relationship and select parent and child I have a onetomany relationship. Using criteria builder, i need to get parent and all related childs but selecting only some fields from each child.

@Entity
@Table(name="transaction_status")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TransactionStatus implements Serializable {
@Id
@Column(name = "id")
@JsonProperty("id")
public String id;

@SerializedName("status")
public String status;

@Column(name="lastUpdatedDate")
@JsonProperty("lastUpdatedDate")
@SerializedName("lastUpdatedDate")
private Date lastUpdatedDate;

@JsonProperty("generatedAt")
@SerializedName("generatedAt")
@JsonIgnore
private Date generatedAt;

@JsonProperty("invoices")
@SerializedName("invoices")
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="transactionstatusId",referencedColumnName = "xmlFilename")
private List<InvoiceTransaction> invoiceTransactions = new ArrayList<>();

}

@Entity
@Table(name="invoice_transaction")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor

public class InvoiceTransaction implements Serializable {
    @Column(name = "status", nullable = false)
    @JsonProperty("status")
    @SerializedName("status")
    private String status;
    @Column(name = "originalStatus", nullable = false)
    @JsonProperty("originalStatus")
    @SerializedName("originalStatus")
    private String originalStatus;
    
    @Column(name = "errorMessage")
    @JsonProperty("errorMessage")
    @SerializedName("errorMessage")
    private String errorMessage;

    @Column(name = "generatedAt" )
    @JsonProperty("generatedAt")
    @SerializedName("generatedAt")
    private Date generatedAt;
}

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<TransactionStatus> cq = builder.createQuery(TransactionStatus.class);
Root<TransactionStatus> rootTrnStatus = cq.from(TransactionStatus.class);
List<TransactionStatus> resultList = entityManager.createQuery(cq).getResultList();

this implementation, gives me list of Transactionstatus objetc with list of its childs. what im seraching to get is: list of Transactionstatus object with list of its childs with olny status and errorMessage fileds. How can i get this result using Crtiteria builder? thank you

How to handle CrudRepository exceptions with showing error message on page from where the form was submitted?

The function below handles form submission to change a user data in the database (save, delete):

@PostMapping(consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String manageUser(@RequestBody MultiValueMap<String, String> formData, HttpServletRequest request) {
    Long userId = Long.valueOf(formData.getFirst("userId"));
    Long id = Long.valueOf(formData.getFirst("id"));
    String username = formData.getFirst("username");
    String password = formData.getFirst("password");
    User changedUserData = new User(id, username, password);
    List<Role> roles = Arrays.stream(formData.getFirst("roles").split(","))
            .map(roleName -> new Role(0L, changedUserData, roleName))
            .collect(Collectors.toList());
    changedUserData.setRoles(roles);
    String actionName = formData.getFirst(ACTION_SAVE) != null ? ACTION_SAVE : ACTION_DELETE;
    if (ACTION_SAVE.equals(actionName)) {
        userRepository.save(changedUserData);
    } else if (ACTION_DELETE.equals(actionName)) {
        userRepository.deleteById(userId);
    }
    return "redirect:" + request.getHeader("referer");
}

I use userRepository.save(changedUserData). This function doesn't throw any excpetions to find out whether there are any errors or not. I have read something about Spring's "exception translating mechanism" but I don't know how to apply it in my situation.

I want that when an exception was thrown the error message is displayed on the page from where the form was submitted (passing as model attributes to Thymeleaf or redirecting with flash attributes).

Validation failed for query for method public abstract util.List

I am new to Spring Data JPA, so I am having a trouble writing queries. I want to get all actors that had role in a certain movie that I get from movieID.

When trying this, I get error while trying to start :

Validation failed for query for method public abstract java.util.List

@Repository
public interface RoleRepository extends JpaRepository<RoleEntity, Long> {

    @Query(value = "select distinct r.actor from RoleEntity r " +
            "where r.movie.movieID = ?1")
    List<ActorEntity> findByMovieID(Long movieID);

}

Here are my entities:

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity(name = "roles")
public class RoleEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long roleID;

    @ManyToOne
    @NotNull
    @JoinColumn(name = "actor_id", referencedColumnName = "id")
    private ActorEntity actor;

    @ManyToOne(fetch = FetchType.LAZY)
    @NotNull
    @JoinColumn(name = "movie_id", referencedColumnName = "id")
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    private MovieEntity movie;

    private String roleName;

}
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Table(name="actor")
public class ActorEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long actorID;

    @NotEmpty
    private String firstName;

    @NotEmpty
    private String lastName;

    @Enumerated(EnumType.STRING)
    private Gender gender;

    @OneToMany(mappedBy = "actor", cascade = CascadeType.ALL)
    @JsonBackReference
    private Set<RoleEntity> roles = new HashSet<>();

}




@Getter
@Setter
@ToString
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "movie")
public class MovieEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long movieID;

    @NotEmpty
    private String name;

    @NotEmpty
    private String description;

    @NotEmpty
    private String duration;

    @NotNull
    private LocalDate startTime;

    private LocalDate endTime;

    @OneToMany(mappedBy = "movie", cascade = CascadeType.ALL)
    private Set<RoleEntity> roles = new HashSet<>();

    @OneToMany(mappedBy = "movie", cascade = CascadeType.ALL)
    private Set<ProjectEntity> projects = new HashSet<>();

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
            name = "movie_genres",
            joinColumns = @JoinColumn(name = "movie_id"),
            inverseJoinColumns = @JoinColumn(name = "genre_id"))
    private Set<GenreEntity> genres;

}

I tried using native query, but it says it returns Long?!

@Query(value = "select a.id, a.first_name, a.last_name, a.gender " +
        "from actor a " +
        "join roles r on r.actor_id = a.id " +
        "where r.movie_id = ?1", nativeQuery = true)
List<ActorEntity> findByMovieID(Long movieID);

Thank you very much in advance!!! :D

uninitialized proxy passed to persist()

I am getting "uninitialized proxy passed to persist()" during persist of an object. What does this mean?

org.hibernate.PersistentObjectException: uninitialized proxy passed to persist()

The entity has one many to many relationship, as

@ManyToOne @JoinColumn(name="brand_id") private Brand brand;

and one OneToOne relationship as,

    @OneToOne(cascade=CascadeType.ALL , fetch=FetchType.LAZY)
    @JoinColumn(name="addressToSendAC_FK")
    private BrandAddress addressToSendAC; 

Are these causing the error ?

Edit:

stacktrace added.

[#|2011-06-30T14:36:29.920+0530|SEVERE|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=58;_ThreadName=Thread-1;|javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: uninitialized proxy passed to persist()
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1214)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1147)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1153)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:678)
    at com.wompower.entity.accessor.brand.BrandRegistry$11.execute(BrandRegistry.java:271)
    at com.wompower.entity.accessor.common.AbstractEntityAccessor.doInTransaction(AbstractEntityAccessor.java:82)
    at com.wompower.entity.accessor.brand.BrandRegistry.addBrandAC(BrandRegistry.java:267)
    at com.wompower.backing.brand.ActivationCodeBacking.generateActivationCode(ActivationCodeBacking.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:613)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:98)
    at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:148)
    at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
    at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:772)
    at javax.faces.component.UICommand.broadcast(UICommand.java:300)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:775)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1267)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
    at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:115)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
    at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:820)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:517)
    at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:488)
    at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:379)
    at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:336)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:314)
    at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:277)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
    at java.lang.Thread.run(Thread.java:729)

Caused by: org.hibernate.PersistentObjectException: uninitialized proxy passed to persist()
    at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:83)
    at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:799)
    at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:791)
    at org.hibernate.engine.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:48)
    at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
    at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
    at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:450)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:282)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:143)
    at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:69)
    at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:179)
    at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
    at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:799)
    at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:791)
    at org.hibernate.engine.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:48)
    at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
    at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
    at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:450)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:282)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:143)
    at org.hibernate.ejb.|#]

[#|2011-06-30T14:36:29.920+0530|SEVERE|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=58;_ThreadName=Thread-1;|event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:69)
    at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:179)
    at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
    at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
    at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:808)
    at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:782)
    at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:786)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:672)
    ... 63 more

JPA SPECIFICATION WITH INTERFACE PROJECTIONS

I have problems that how to implement jpa specification with parameters and dynamic where whose response should be a list of interface projections containing some columns of 3 related entities, because findAll generated error because the specification is about an entity and I hope a list of interface projection like answer, indicate clash

I need an example how implement it

Spring @Transactional(Propagation.NEVER) should create Hibernate session?

Let's assume that we have correctly configured JPA backed by Hibernate (version 4.3.11) in Spring (version 4.2.7). Hibernate first level cache is enabled. We use declarative transactions.

We have OuterBean:

@Service
public class OuterBean {

    @Resource
    private UserDao userDao;

    @Resource
    private InnerBean innerBean;

    @Transactional(propagation = Propagation.NEVER)
    public void withoutTransaction() {
        User user = userDao.load(1l);
        System.out.println(user.getName());  // returns "userName"

        // this call is supposed to change the initial user name
        innerBean.withTransaction();

        user = userDao.load(1l);
        System.out.println(user.getName());  // still returns "userName" instead of "newUserName"
    }

}

And InnerBean that is called from OuterBean:

@Service
public class InnerBean {

    @Resource
    private UserDao userDao;

    @Transactional
    public void withTransaction() {
        User user = userDao.load(1l);
        user.setName("newUserName");
    }

}

Is it correct behaviour that method user.getName() in OuterBean returns the same value twice (second time is after update name in database)?

In other words is it correct behaviour that @Transactional(propagation = Propagation.NEVER) annotation creates Hibernate session for method withoutTransaction() that causes that second call user.getName() reads from Hibernate first level cache instead of database?


EDIT

To explain the problem more I'm attaching the traces from creation of Hibernate sessions:

TRACE org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl  - Opening Hibernate Session.  tenant=null, owner=org.hibernate.jpa.internal.EntityManagerImpl@c17285e
TRACE org.hibernate.internal.SessionImpl  - Opened session at timestamp: 14689173439
TRACE org.hibernate.internal.SessionImpl  - Setting flush mode to: AUTO
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
userName
TRACE org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl  - Opening Hibernate Session.  tenant=null, owner=org.hibernate.jpa.internal.EntityManagerImpl@715c48ca
TRACE org.hibernate.internal.SessionImpl  - Opened session at timestamp: 14689173439
TRACE org.hibernate.internal.SessionImpl  - Setting flush mode to: AUTO
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Automatically flushing session
TRACE org.hibernate.internal.SessionImpl  - before transaction completion
TRACE org.hibernate.internal.SessionImpl  - after transaction completion
TRACE org.hibernate.internal.SessionImpl  - Closing session
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
userName
TRACE org.hibernate.internal.SessionImpl  - Closing session

Now let's compare with the traces when I remove @Transactional(propagation = Propagation.NEVER) annotation:

TRACE org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl  - Opening Hibernate Session.  tenant=null, owner=org.hibernate.jpa.internal.EntityManagerImpl@4ebd2c5f
TRACE org.hibernate.internal.SessionImpl  - Opened session at timestamp: 14689203905
TRACE org.hibernate.internal.SessionImpl  - Setting flush mode to: AUTO
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Closing session
userName
TRACE org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl  - Opening Hibernate Session.  tenant=null, owner=org.hibernate.jpa.internal.EntityManagerImpl@5af84083
TRACE org.hibernate.internal.SessionImpl  - Opened session at timestamp: 14689203905
TRACE org.hibernate.internal.SessionImpl  - Setting flush mode to: AUTO
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Automatically flushing session
TRACE org.hibernate.internal.SessionImpl  - before transaction completion
TRACE org.hibernate.internal.SessionImpl  - after transaction completion
TRACE org.hibernate.internal.SessionImpl  - Closing session
TRACE org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl  - Opening Hibernate Session.  tenant=null, owner=org.hibernate.jpa.internal.EntityManagerImpl@35f4f41f
TRACE org.hibernate.internal.SessionImpl  - Opened session at timestamp: 14689203906
TRACE org.hibernate.internal.SessionImpl  - Setting flush mode to: AUTO
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Setting cache mode to: NORMAL
TRACE org.hibernate.internal.SessionImpl  - Closing session
newUserName

Please notice when I omit @Transactional(propagation = Propagation.NEVER) annotation a separate session is created for every invocation of method from userDao.

So my question can be formulated also as

Shouldnโ€™t be @Transactional(propagation = Propagation.NEVER) implemented in Spring as a guardian that prevents us from accidental use of transaction, without any side effect (session creation)?

SpringBoot unit test does not use @EnableAutoConfiguration annotation from Application class

I want to configure a Spring Boot Application so that no DB is used at all. So I have annotated my Application class for excluding JPA autoconfig classes:

@SpringBootApplication
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class Application {

    public static void main(final String... args) {
        run(Application.class, args);
    }
}

This works fine when the service is run standalone

Unfortunately my test classe seems to ignore the annotation, although I use the Application class for my test

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SwaggerJsonExistenceTest {
    ...
}

The test fails with the following error message

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Cannot determine embedded database for tests. If you want an embedded database please put a supported one on the classpath.

Update: There are no DB drivers on the classpath.

org.springframework.boot:spring-boot-starter-data-jpa is used for testing (included via testCompile directive in gradle)

How has the test to be configured so that it does not use db-related autoconfiguration?

Fix: I have removed all jpa starter dependencies (as no DB is needed), so that datasource autoconfig is not done at all.

Custom implementation of getCurrentAuditor method returns error when trying to use a JPA repository

I have a user entity with an audit field named lastUpdatedUserId(same as LastModifiedBy). This is an integer field. I'm trying to use the auditing feature provided by Spring and did everything stated in the docs. When I tried to override the getCurrentAuditor method of AuditorAware, it works fine if I hardcode an integer as the return value. If I try to use UserRepository(a JPA repository) to get the user id of the logged in user, I get a 'Could not commit JPA transaction' error. I'm using Gmail Oauth2 for authentication. The stacktrace is too long for me to post here. I tried to debug, but it has not been easy.

If any of you know the reason, please let me know.

@EntityListeners(AuditingEntityListener.class)
public class User {
    @LastModifiedBy
    @Column(name = "lst_updtd_usr_id")
    private Integer lastUpdatedUserId;
    ...
}

public class AuditorAwareImpl implements AuditorAware<Integer> {

    @Autowired
    private UserRepository userRepo;

   @Override
   public Optional<Integer> getCurrentAuditor() {
    // your custom logic
    
    DefaultOidcUser oidcUser = (DefaultOidcUser)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    String emailId = oidcUser.getEmail();
    User user = userRepo.findByEmailId(emailId);
    return Optional.of(user.getUserId());
}

}

@Configuration
@EnableJpaAuditing(auditorAwareRef="auditorProvider")
public class PersistenceConfig {

@Bean
AuditorAware<Integer> auditorProvider() {
    return new AuditorAwareImpl();
}

}

Detached entity passed to persist, but the entity was just persisted

I'm getting this error that I shouldn't be getting. First, I persist an appointment1, with doctor1, and it gets saved. Then, on appointment4, I get detached entity error, but doctor1 is already saved = it has an ID set, it's in the database. What's going on? What's the resolution? Thank you.

Appointment appointment1 = new Appointment("08/11/11", patient1,
        payment1, doctor1);
Appointment appointment2 = new Appointment("12-11-2008", patient2,
        payment2, doctor2);
Appointment appointment3 = new Appointment("13-11-2008", patient3,
        payment3, doctor2);
Appointment appointment4 = new Appointment("14-11-2008", patient1,
        payment4, doctor1);

appointmentRepository.save(appointment1);
// detached entity passed to persist: domain.Doctor
appointmentRepository.save(appointment4);

Hibernate creates a new sequence instead of using existing one and fails

I have a preexisting Postgres database with a bunch of tables. Each table has an ID column with a sequence. In my entity class I have something like this:

@Entity
@Table(name = "plan_block")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Audited
public class Block {
    @Id
    @GeneratedValue(generator = "plan_block_block_id_seq")
    @SequenceGenerator(allocationSize = 1, name = "plan_block_block_id_seq", sequenceName = "plan_block_block_id_seq")
    @Column(name = "block_id", nullable = false, insertable = false, updatable = false)
    private Long id;
...

The sequence does exist in the database. When I run the project I get

GenerationTarget encountered exception accepting command : Error executing DDL "create sequence "plan_block_block_id_seq" start with 1 increment by 1" via JDBC [ERROR: relation "plan_block_block_id_seq" already exists]

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create sequence "plan_block_block_id_seq" start with 1 increment by 1" via JDBC [ERROR: relation "plan_block_block_id_seq" already exists]

for every single sequence I declared.

I tried adding strategy to GeneratedValue annotation, setting allocationSize or initialValue to the SequenceGenerator annotation.

UPD: I want to use that existing sequence because I already have a bunch of rows in the table

Unique constraints with Spring Data not applied in MySQL database

I have this entity defined:

@Entity
@Table(name = "t_transit_aspect_western_es",
        uniqueConstraints =
        @UniqueConstraint(columnNames = {
                "transitPlanet",
                "transitSign",
                "transitHouse",

                "natalPlanet",
                "natalSign",
                "natalHouse",

                "type",
                "isRetrograde",
                "lang"}))
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
@Slf4j
public class TransitAspectWesternEs implements Serializable {

I was able to insert two records with the same values and natal_house=null without any exception from MySQL.

Why does returning Set from a Spring Data JPA Repository works although it shouldn't?

I have a simple JpaRepository like that:

public interface GroupRepository extends JpaRepository<Group, Integer> {
    
    Set<Group> findAllByStudentsStudentId(Long studentId);
    
}

According to this Baeldung article as well as to these Supported Query Return Types, returning a Set shouldn't function out of the box. Therefore I assume, that Spring Data JPA somehow converts the return type into a set anyway.

My questions are:

  1. Why is this possible although nowhere mentioned (or did I missunderstand something)?
  2. If Spring converts the return type, does Spring convert afterwards, meaning first a List (or Iterable) is build and then as a followup operation the List gets turned into a Set, or is the Set in place right from the start while the result rows get merged into their entities?

Many thanks for any clarification

How to globally map boolean fields onto smallint in Eclipeselink on postgres

Hello I was trying to configure eclipselink to save boolean fields to smallint We are migrating from oracle where booleans were mapped onto number(1) and would like to retain numeric value to prevent potential breakage of related (non jpa) systems consuming our tables directly.

Updating any boolean field results in [code] Caused by: org.postgresql.util.PSQLException: ERROR: column "is_active" is of type smallint but expression is of type boolean Hint: You will need to rewrite or cast the expression. [/code]

I can, of course, use eclipselink converters but I do not want to explicitly annotate every boolean field (and useautoApply = true on a such a common type as boolean field - i guess I could but it is rather all inclusive and also may have some performance implication ).

So I was looking for a way to tweak Postgres platform class but could not identify any point where I can do it

I looked into PostgreSQLPlatform and its superclasses and also was trying to trace where I can do it in other classes. It does not look like eclipselink consults platform classes for direct mapping fields. it also does not appear that when handling boolean fields eclipselink chacks JDBC Type at all to alter its behavior (would have been nice when writing/reading boolean to a row/parameter to check its JDBC type and do basic conversion to 0/1

Any suggestions would be greatly appreciated

Thank you, Alex

spent hours with debugger trying to figure out where field value is converted to row/parameter value and why no check on field metadata JDBC type is being made to support basic type conversion such as boolean and int or bit

How to select all row and give boolean mark the row with max value of a column (with multiple marking)? (Java Native Query, Psql)

Currently I am working on giving a label to my data. I will give the label to data that marked as highest on the resulting query. the problem is the label is not only for 1 case but multiple, and also I need pagination for the query using Pageable.

*Note: I need it by query because I think it's not feasible to do in Java because 1. the API might have big number of hit, 2. the logic of pagination containing page_number and page_size and sorting query.


Example of data

id name power heigh
uuid1 ace 1000 170
uuid2 luffy 990 168
uuid3 zorro 980 167
uuid4 sanji 970 180

Mocked result that I wanted when I queried is like this

id name power is_highest_power heigh is_highest_heigh
uuid1 ace 1000 true 170 false
uuid2 luffy 990 false 168 false
uuid3 zorro 980 false 167 false
uuid4 sanji 970 false 180 true

Currently, working on it with Postgresql db with java JPARepository interface. I need to build the native query with pagination in it and also a filter for the result.

@Query(
      nativeQuery = true,
      countQuery = "SELECT count(1) "
          + " FROM user u "
          + " WHERE (:startPower IS NULL OR u.power >= :startPower) AND "
          + " (:startHeigh IS NULL OR u.heigh >= :startHeigh)",
      value = "SELECT u.id, u.name, u.power, u.is_highest_power (??), u.heigh, "
          + " u.is_highest_heigh (??)"
          + " FROM user u "
          + " WHERE (:startPower IS NULL OR u.power >= :startPower) AND "
          + " (:startHeigh IS NULL OR u.heigh >= :startHeigh)"
  )
  Page<SearchUser> searchUser(
      Pageable pageable,
      BigDecimal startPower,
      BigDecimal startHeigh
  );


public interface SearchUser {

  @Value("#{target.id}")
  String getId();

  @Value("#{target.name}")
  String getName();

  @Value("#{target.power}")
  BigDecimal getPower();

  @Value("#{target.is_highest_power}")
  Boolean getIsHighestPower();

  @Value("#{target.heigh}")
  BigDecimal getHeigh();

  @Value("#{target.is_highest_heigh}")
  Boolean getIsHighestHeigh();

I have found how to query to get the highest power or heigh (as mentioned here) but can not found how to mark a row as the highest and query it as the result column too.

How to achieve this in nativeQuery string?

JPA. Specification, Implementation or both?

I study the JPA. The book uses classes, interfaces and annotations from javax.persistence package like @Entity,@Table,EntityManager etc to make a real and functional ORM application. When I searched to the Internet about JPA I read a few articles that said "JPA is just a specification, it doesn't perform any operation by itself. It requires an implementation (like Hibernate,TopLink etc)". And then what are all those classes in the javax.persistence??? Am I missing something?

Need Help Generating ID in Spring Boot JPA Entity Class Before Saving to Database

I have an entity class in my Spring Boot application where I've implemented a custom ID generator for the ID field. However, the ID isn't generated upon constructing the entity using the default constructor. I need the ID to be auto-generated when I create a new instance of the entity, like this: TransactionsEntity myEntity = new TransactionsEntity(); and then call myEntity.getId() to retrieve the generated ID.

Here's my Entity Class:

@Entity
@Table(name = "transactions")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class TransactionsEntity {

    @Id
    @NonNull
    @Column(name = "transactionNumber", columnDefinition = "varchar(18)", length = 18)
    @GeneratedValue(generator = SequenceGenerator.generatorName)
    @GenericGenerator(name = SequenceGenerator.generatorName, strategy = "com.vendify.Dependencies.Tools.Spring.Generators.SequenceGenerator")
    private String transactionNumber;
}

And this is my Generator:

public class SequenceGenerator implements IdentifierGenerator {
    public static final String generatorName = "6CharGenerator";

    @Override
    public Serializable generate(SharedSessionContractImplementor sharedSessionContractImplementor, Object o) throws HibernateException {
        return RandomGenerator.GenerateRandomStringUpperCaseOnlyNoSimilarChars(6);
    }
}

Despite this setup, the constructor doesn't generate an ID as intended. I would greatly appreciate any guidance or help in resolving this issue!

โŒ
โŒ