Here is my repository:
public interface MachineRepository extends JpaRepository<Machine, Integer> {
#Query(value="select m.name FROM Machine m", nativeQuery = true)
Set<SomeName> getAllMachineTypes();
}
Interface:
public interface SomeName {
String getName();
}
Model:
#Data
#Entity
#Table(name="Machine")
public class Machine {
#Id
#Column(name = "id")
#GeneratedValue
private Integer id;
#Column(name = "name")
private String name;
}
Service:
#Service
public class MachineService {
#Autowired
MachineRepository machineRepository;
public Set<SomeName> getAllMachines(){
return machineRepository.getAllMachines();
}
Controller:
#Autowired
MachineService machineService;
#RequestMapping("/")
public String findMachines(){
Set<SomeName> machines = machineService.getAllMachines();
for (SomeName mch: machines
) {
System.out.println(mch.getName());
}
//...
}
When I run as it is, it prints the name to the console. But when I change nativeQuery to false (or remove it because it is false by default):
public interface MachineRepository extends JpaRepository<Machine, Integer> {
#Query(value="select m.name FROM Machine m", nativeQuery = false)
Set<SomeName> getAllMachineTypes();
}
Then I don't get any output.
Since I don't want to use nativeQuery, I would like to ask how to make it work without it.
Use this:
public interface MachineRepository extends JpaRepository<Machine, Integer> {
#Query(value="select m.name FROM Machine m")
List<String> getAllMachineTypes();
}
because m.name is a String.
Related
I want to filter motherName and sisterName but I don't know how to write a filter for embedded class. Please help me to solve this issue. Thank you in advance!
Family1 class
#Entity
public class Family1 {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
private int id;
#Embedded
private FamilyNames familyNames;
#Column(nullable=false,name="familyMemebers")
private int familyMembers;
#Column(nullable=false,name="contactNo")
private long contactNo;
#Embedded
#Column(nullable=false, name="Address" )
private Address address;
public Family1() {}
// getters,setters
FamilyNames class
#Embeddable
public class FamilyNames {
private String yourName;
private String fatherName;
private String motherName;
private String sisterName;
public FamilyNames() {}
//getters, setters
Family1Controller class
#RestController
#RequestMapping(value = "/family1")
public class Family1Controller {
#Autowired
private Family1Service family1Service;
#RequestMapping(method=RequestMethod.GET,value="/fam1")
public List<Family1> listOfDetails(#RequestParam("keyword") String keyWord){
return family1Service.listOfDetails(keyWord);
}
}
Family1Service class
#Service
public class Family1Service {
#Autowired
private Family1Repository familyRepository;
public List<Family1> listOfDetails(String keyWord) {
return familyRepository.findAll();
}
}
Family1Repository class:
#Repository
public interface Family1Repository extends JpaRepository<Family1,Integer> {
#Query("Select f from family1 f where f.familyNames.motherName LIKE %?1%"
+ "OR f.familyNames.sisterName %?1%")
List<Family1> findAll(String keyWord);
}
please help me which way to filter particular name in embedded class using query annotation
Try to use the following query:
#Query(
"select f from Family1 f where f.familyNames.motherName LIKE '%' || :name || '%'"
+" OR f.familyNames.sisterName LIKE '%' || :name || '%'")
List<Family1> findAll(#Param("name") String keyWord);
I have an entity which contains field date.
#Entity
#Table(name="messages", schema = "users")
...
public class Message {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "author")
private String author;
#Column(name = "tags")
private String tags;
#Column(name = "message_date")
private LocalDate date;
#Override
public String toString() {
...
}
}
#Repository
public interface MessageRepository extends JpaRepository<Message, Long> {
Message findByMessageId(Long id);
}
I'm using Spring Data JPA with repository. I want to get all messages from database for last 3 days (field date). How can I do it with Spring JPA?
#Query(...?)
List<Message> findBy...?
I suggest to split the logic from the actual queries. A service could handle all the intermediate things, e.g.:
#Service
public class MessageService {
private final MessageRepository repository;
#Autowired
public MessageService(MessageRepository repository) {
this.repository = repository;
}
List<Message> getLastThreeDays() {
// subtract 3 days from today
LocalDate threeDaysAgoDate = LocalDate.now().minusDays(3);
return this.repository.findAllWithDateAfter(threeDaysAgoDate);
}
}
and your repository stays nice and clean:
#Repository
public interface MessageRepository extends JpaRepository<Message, Long> {
Optional<Message> findByMessageId(Long id);
#Query("select m from Message m where date >= :threeDaysAgoDate")
List<Message> findAllWithDateAfter(#Param("threeDaysAgoDate") LocalDate threeDaysAgoDate);
}
I am new in spring/hibernate technologies, I have tried to find an information about it, but failed, so if you can help I will be so thankful!
I need to display a JSON response in browser of multiple tables, one of the table has primary key for another one.
My entities:
#Entity
#Table
#ToString
public class Book {
#Id
#GeneratedValue(strategy = AUTO)
#JsonView(Views.IdName.class)
private Long book_id;
#JsonView(Views.IdName.class)
private String name;
#Column(length = 1000000)
private String text;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="author_id")
#JsonView(Views.IdName.class)
private Author author;
// ....get/set methods
Another one:
#Entity
#Table
#ToString
public class Page {
#Id
#GeneratedValue(strategy = AUTO)
private Long id;
#Column(length = 1000000)
private String text;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "book_id")
private Book book;
// ...get/set methods
My controllers:
#RestController
#RequestMapping("books")
public class BookController {
private final BookRepo bookRepo;
#Autowired
public BookController(BookRepo bookRepo) {
this.bookRepo = bookRepo;
}
#GetMapping
#JsonView(Views.IdName.class)
public List<Book> getAll() {
return bookRepo.findAll();
}
#GetMapping("{id}")
public Book getOne(#PathVariable("id") Book book) {
return book;
}
}
Another one:
#RestController
#RequestMapping("authors")
public class AuthorController {
private final AuthorRepo authorRepo;
#Autowired
public AuthorController(AuthorRepo authorRepo) {
this.authorRepo = authorRepo;
}
#GetMapping
public List<Author> getAll() {
return authorRepo.findAll();
}
#GetMapping("{id}")
public Optional<Author> getOne(#PathVariable("id") Long id) {
return authorRepo.findById(id);
}
}
And also repo for interaction with DB (they are the similar):
public interface AuthorRepo extends JpaRepository<Author, Long> {
}
So when I make a request for get all books, I take the following JSON:
enter image description here
Bit I want different result, something like:
[
{
"book_id" : 1,
"name": "name 1 book",
"author" :
{
"author_id" : 1,
"name": "some_name"
}
}
]
Also, when I tried to make a request for /authors/1, I will get the following response (something like recursion) :
enter image description here
So any help how can I handle with it? Thank you!
You can use a #NoRepositoryBean
like in this example:
#NoRepositoryBean
public interface MappedTypeRepository<T extends AbstractMappedType>
extends Repository<T, Long> {
#Query("select new com.example.YourObjectWithConstructor(e.attribute, sub.sub_attribute) from entity e inner join e.subtable sub where e.attribute = ?1")
List<YourObjectWithConstructor> findAllByAttribute(String attribute);
}
My example may not be 100% correct, I did not check the syntax. Feel free to explore it
Check this also:
JPQL Create new Object In Select Statement - avoid or embrace?
Is it possible to combine two DAOs into one Service method?
I want to create a generic method which will choose correct DAO based on the input parameter. What for now I came up with is the method which will accept Dao from the outside the service object. But this requires to initialize appropriate Dao in the Controller which is a little bit ugly...
Measurement is just an interface for Temperature.java and Humidity.java entities with separate tables on PostgreSQL.
#Service
public class MeasurementService {
#Autowired
private TemperatureDao temperatureDao;
#Autowired
private HumidityDao humidityDao;
public<T extends PagingAndSortingRepository<Measurement, Long>> void insertMeasurementForUser(String username, List<Measurement> measurements, T dao) {
dao.saveAll(measurements);
}
}
TemperatureDao.java
#Repository
public interface TemperatureDao extends PagingAndSortingRepository<Temperature, Long> {
#Query("select u from Temperature u where u.owner = ?1 order by u.id desc")
List<Temperature> findLatestTemperatureForUser(User user, Pageable pageable);
}
HumidityDao.java
#Repository
public interface HumidityDao extends PagingAndSortingRepository<Humidity, Long> {
#Query("select u from Humidity u where u.owner = ?1 order by u.id desc")
List<Humidity> findLatestHumidityForUser(User user, Pageable pageable);
}
Temperature.java
#Entity
#Table(name = "temperature")
public class Temperature implements Measurement {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
#Column(name = "th1value")
private Float th1Value;
#Column(name = "timestamp")
#NotNull
private LocalDateTime timestamp;
#ManyToOne
#JoinColumn(name = "user_id")
#NotNull
private User owner;
public Temperature() {
}
public Temperature(Float th1Value, LocalDateTime timestamp, User owner) {
this.th1Value = th1Value;
this.timestamp = timestamp;
this.owner = owner;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#JsonDeserialize(using = LocalDateTimeDeserializer.class)
public LocalDateTime getTimestamp() {
return timestamp;
}
#JsonSerialize(using = LocalDateTimeSerializer.class)
public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}
#Override
public User getOwner() {
return owner;
}
#Override
public void setOwner(User owner) {
this.owner = owner;
}
}
Humidity.java
#Entity
#Table(name = "humidity")
public class Humidity {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
#Column(name = "hum1value")
private Float hum1Value;
#Column(name = "timestamp")
#NotNull
private LocalDateTime timestamp;
#ManyToOne
#JoinColumn(name = "user_id")
#NotNull
private User owner;
public Humidity() {
}
public Humidity(Float hum1Value, LocalDateTime timestamp, User owner) {
this.hum1Value = hum1Value;
this.timestamp = timestamp;
this.owner = owner;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#JsonDeserialize(using = LocalDateTimeDeserializer.class)
public LocalDateTime getTimestamp() {
return timestamp;
}
#JsonSerialize(using = LocalDateTimeSerializer.class)
public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
}
Any ideas?
You could write a Resolver pattern to return needed dao based on your conditions. You service will use the resolver to get the correct dao.
public HellDao implements BaseDao {
public void save();
}
public ByeDao implements BaseDao {
public void save();
}
public DaoResolver {
#Autowired
private helloDao;
#Autowired
private byeDao;
public BaseDao resolve(Object input) {
//based on input return the correct dao
BaseDao resolvedDao = null;
switch(input.enum) {
case Hello:
resolvedDao = helloDao;
break;
case Hello:
resolvedDao = byeDao;
break;
default:
//decide something for default
}
return resolvedDao;
}
}
public class MyService {
#Autowired
private DaoResolver daoResolver;
public Object doSomething() {
BaseDao dao = daoResolver.resolve(someObject);
//you will get HelloDao or ByeDao based on the input
dao.save();
}
}
You can check for the type of measurements using instanceof so you could do it without generics.
public void insertMeasurementForUser(String username, List<Measurement> measurements) {
if(measurements.get(0) instanceof Temperature)
temperatureDao.saveAll(measurements);
else if(measurements.get(0) instanceof Humidity)
humidityDao.saveAll(measurements);
}
I have UserRepository:
public interface UserRepository extends JpaRepository<User, String> {}
The entity:
#Entity
#Table(schema="test", name = "TBL_USERS")
#Builder
#AllArgsConstructor
public class User implements Persistable<String> {
#Id
#Column(name = "ID", columnDefinition = "char")
private String id;
#NotNull
#Column(name = "NAME", columnDefinition = "char", nullable = false)
private String name;
...
}
And in my test I want to count records with certain name like the query:
select count(*) from TBL_USERS where name='John';
#Test
public void testCountSimilarNames() {
...
userRepository.count() ... ?
}
I use latest spring-boot.
You need something like :
public interface UserRepository extends CrudRepository<User , String >{
Integer countByName(String name);
}