microservice seems to work, but there's no data displayed - postgresql

I have a simple app that's supposed to connect to postgres and display content of one of the tables.
I installed postgres, created a table and inserted a row, but nothing is shown when I run it.
This are my application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=name
spring.datasource.password=pass
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
and this is repository interface
#Repository
public interface TaxonRepository extends CrudRepository<Taxon, Long> {
}
and the model
#Entity
#Table(name = "dim_taxon")
public class Taxon{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Getter #Setter
private Long id;
#Getter #Setter
private String name;
#Getter #Setter
private String value;
#Getter #Setter
private String reserve;
#Getter #Setter
private String source;
}
My service
#Service
public class TaxonService implements TaxonServiceI{
#Autowired
private TaxonRepository repository;
#Override
public List<Taxon> findAll() {
return (List<Taxon>) repository.findAll();
}
}
and controller
#Controller
public class TaxonController {
#Autowired
private TaxonServiceI taxonService;
#RequestMapping(value="/showTaxons")
public String homePage(Model model){
List<Taxon> taxons = taxonService.findAll();
model.addAttribute("taxons", taxons);
return "index";
}
}
I tried to add an object manually to check if there was a problem with the html or smth
List<Taxon> taxons = new ArrayList<>();
Taxon taxon1 = new Taxon();
taxon1.setName("a");
taxon1.setReserve("a");
taxon1.setSource("a");
taxon1.setValue("a");
taxons.add(taxon1);
model.addAttribute("taxons", taxons);
but html is fine. Seems like this
List<Taxon> taxons = taxonService.findAll();
doesn't work. What's the problem here? There aren't actually any errors.
My table and the data.

You are not adding your loaded List<Taxon> to the model.
#RequestMapping(value="/showTaxons")
public String homePage(Model model){
List<Taxon> taxons = taxonService.findAll();
return "index";
}
Just returns the page to render, without modifying the model.
So this should work
#RequestMapping(value="/showTaxons")
public String homePage(Model model){
model.add(taxonService.findAll());
return "index";
}

In the end I added a few more anotations
#Data
#NoArgsConstructor
#AllArgsConstructor
#Validated
#Entity
#Table(name = "table name")
And explicit mapping for columns
#Column(name = "column_name")
this helped

Related

Why JPA update entity causes stackoverflow?

I have an entity Task with id. Tasks belongs to Config. I need to update Task with it's Config doesn't change. Here is my code:
Task:
#Entity
#Getter
#Setter
public class Task{
#ManyToOne
#JoinColumn(name = "config_id", referencedColumnName = "id")
private Config config;
#OneToMany(orphanRemoval = true,cascade = CascadeType.ALL)
#JoinColumn(name="task_id")
private Set<ActivityItemTask> activityItemTasks = new HashSet<>();
}
#Entity
public class ActivityItemTask {
private Double score;
#EmbeddedId
private ActivityItemTaskId activityItemTaskId;
#Getter
#Setter
#Embeddable
#NoArgsConstructor
#AllArgsConstructor
public static class ActivityItemTaskId implements Serializable {
#ManyToOne
#JoinColumn(name = "activity_item_id")
private ActivityItem activityItem;
#ManyToOne
#JoinColumn(name = "task_id")
private Task task;
#ManyToOne
#JoinColumn(name = "config_id")
private TaskConfig config;
}
}
Config:
#Entity
#Getter
#Setter
public class Config{
#OneToMany(mappedBy = "config")
private Set<Task> tasks = new HashSet<>();
}
TaskService:
#Service
public class TaskService{
#Resource
TaskRepository taskRepository;
#Transactional
public Long save(Taskdto dto){
Config config = new Config();
config.setId(task.getConfigId());
s.setTaskConfig(config);
return taskRepository.save(s).getId();
}
}
TaskDto:
#Data
public class TaskDto {
private Long id;
#NotNull
private Long configId;
private String name;
private Date beginDate;
private Date endDate;
private String note;
}
when TaskService#save was called , it throw StackOverflowException:
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.StackOverflowError
the log shows that my application querys task record and querys task's config and config's tasks and so on.
I am wondering what's wrong with my association annation. Any advice are appreciated.
I'm sorry.I have written another 2 calss so that I can find out the truth. It turns out my third calss ActivityItemTask may be the root cause. I think Task. activityItemTasks may should be annnotation with mappedBy=? But which field should be writtern here?
I did config wrong association.
Task should be :
#OneToMany(mappedBy = "activityItemTaskId.task")
// #JoinColumn(name = "task_id")
private Set<ActivityItemTask> activityItemTasks = new HashSet<>();
This is how to use mappedBy annotation with embedable class.
Thank all you guys commented or answered. You did help me find it out.

Why JPQL ignore parent's fields?

App's stack: Hibernate, Spring Data, JPA.
There are some entities in the app. I try make JPQL-query in repository of my class OpenParagraph.
OpenParagraph:
#Entity
#Table(name = "open_paragraphs")
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#ToString
public class OpenParagraph extends ProgramEntry {
#NotNull
#Column(name = "sort_num")
private Integer sortNum;
}
OpenParagraph has a parent: abstract class ProgramEntry.
ProgramEntry:
#MappedSuperclass
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#ToString
public abstract class ProgramEntry extends AbstractBaseEntity {
#NotNull
#ManyToOne
#JoinColumn(name = "paragraph_id")
private Paragraph paragraph;
#NotNull
#ManyToOne
#JoinColumn(name = "program_id")
private Program program;
}
So, i tring to appeal to OpenParagraph's field "Paragraph", but IDEA tells me it's mistake:
It doesn't offer me the "program" field:
IDEA offer fields only from OpenParagraph, not from parent.
My question: this is IDEA's fail? If this is'nt IDEA's fail, then how i can call "program" in this query?
This is/was a bug of Intellij IDEA (maybe related to this?). But:
It is possible to query by fields of the super class (or MappedSuperclass). Here is an example:
#MappedSuperclass
#Getter
#Setter
public class Foo extends AbstractPersistable<Long> {
#Column
private String fooValue;
}
#Entity
#Getter
#Setter
public class Bar extends Foo {
#Column
private String barValue;
}
public interface BarRepository extends JpaRepository<Bar, Long> {
#Query("SELECT b FROM Bar b WHERE b.fooValue = ?1")
List<Bar> findByFooValue(String fooValue);
}
Given this, calling the repository method, something like this will be logged (with enabled sql logging):
Hibernate: select bar0_.id as id1_0_, bar0_.foo_value as foo_valu2_0_, bar0_.bar_value as bar_valu3_0_ from bar bar0_ where bar0_.foo_value=?
Hint:
If you are using Spring Boot (with the test dependency/dependencies and an embedded test db like h2), it is quite easy to execute such methods without to run the whole application. Here just a small snipped that would execute the method (even though this is no test, but that's enough to call methods somehow):
#SpringBootTest
public class BarRepositoryTest {
#Autowired
BarRepository barRepository;
#Test
public void testFindByFooValue() {
barRepository.findByFooValue("foo");
}
}

Query for joins in Spring JPA

I have the below entities
#Entity
#Getter
#Setter
public class Aggregate {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(mappedBy = "aggregate")
private Set<Single> singleSet;
}
#Entity
#Getter
#Setter
public class Single {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private String id;
private Integer number;
#ManyToOne
#JoinColumn(name = "agg_id")
private Aggregate aggregate;
}
I also have the below repository
public interface AggregateRepo extends CrudRepository<Aggregate, Long> {
}
I want to return all associated Single records where number in object Single is equal to some random number
I am assuming that the query will be something like this
public interface AggregateRepo extends CrudRepository<Aggregate, Long> {
public List<Single> findBySingleSet_Number(Integer number);
}
However when I try to use Intellij to complete my named query it always populates like this
public interface AggregateRepo extends CrudRepository<Aggregate, Long> {
public List<Single> findBySingleSet_Empty_Number(Integer number);
}
I am wondering what the Empty stands for ?
Also should I create another Single repository since the query is related to returning Single records.

JPA : Entity extend with entity

How can I extend an entity with another entity but both of them referring to the same table ? Is it possible ? The structure is something like this :
#Entity
#Table(name = "users")
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable{
private int id;
private String name;
}
#Entity
#Table(name = "users")
#NamedQuery(name="SubUser.findAll", query="SELECT su FROM SubUser su")
public class SubUser extends User {
#Override
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return super.getId();
}
//- Other fields and getter setter
}
I tried this way Extend JPA entity to add attributes and logic
but I got this exception
org.hibernate.mapping.SingleTableSubclass cannot be cast to org.hibernate.mapping.RootClass
Update 1
I already put the #Id for the SubUser because the #Entity shows this exception
The entity has no primary key attribute defined
Add the #Inheritance annotation to the super class
Implement Serializable
Add a getter for id (you don't need a setter necessarily)
id should be Integer, not int, so that you can represent unassigned ids with null.
Code:
#Entity
#Table(name = "users")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
#Entity
public class SubUser extends User {
}
Any basic JPA docs would describe inheritance, discriminators and use of #Id.
#Entity
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name="DISCRIM", discriminatorType=DiscriminatorType.STRING)
#DiscriminatorValue("User")
#Table(name="users")
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
}
#Entity
#DiscriminatorValue("SubUser")
#NamedQuery(name="SubUser.findAll", query="SELECT su FROM SubUser su")
public class SubUser extends User {
}

Error on em.getTransaction().commit(); using the JPA #Embeddable annotation

I have some problems with #Embeddable in JAVA JPA.
I have an entity class named "Author":
#Entity
#Table(name = "author")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Author.findAll", query = "SELECT a FROM Author a"),
...})
public class Author implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#Column(name = "aID")
private Integer aID;
#Column(name = "aName")
private String aName;
#Column(name = "aSurname")
private String aSurname;
#Column(name = "aPhone")
private Integer aPhone;
#Embedded
#AttributeOverrides({
#AttributeOverride(name="city",column=#Column(name="Address")),
#AttributeOverride(name="street",column=#Column(table="Address")),
#AttributeOverride(name="number",column=#Column(table="Address"))
}) private Address address;
// set and get methods.
}
Also I have an Embeddable class named "Address":
#Embeddable
#Table(name = "Address")
#XmlRootElement
public class Address implements Serializable
{
private static final long serialVersionUID=1L;
#Column(name="city")
private String city;
#Column(name="street")
private String street;
#Column(name="number")
private int number;
// get and set methods.
}
In my main class I want to insert this values to the database. (I use mySQL) But I am getting an error on this line: em.getTransaction.commit();
public class CreateAuthor extends javax.swing.JFrame {
private static final String PERSISTENCE_UNIT_NAME = "Project";
private static EntityManagerFactory emf;
public void CreateAuthor() {
initComponents();
}
private void ekleButtonActionPerformed(java.awt.event.ActionEvent evt) {
emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Author author = new Author();
author.setAID(3);
author.setAName("Sheldon");
author.setASurname("Smith");
author.setAPhone(768987);
Address adr = new Address();
adr.setCity("Paris");
adr.setStreet("cinar");
adr.setNumber(12);
author.setAddress(adr);
em.persist(author);
em.getTransaction().commit(); /// error occured
em.close();
}
}
On my database side, I have Author table (aID(pk),aName,aSurname,aPhone)
Address Table (city,street,number)
Do you have any idea why an error is occured?
The goal of Embeddable is to have fields of an object (Address) stored in the same table as the entity's table (Author -> author).
If you want to save them in another table, than Address should be an entity on its own, and there should be a OneToOne or ManyToOne association between Author and Address. The mapping, as is, don't make any sense.