0% found this document useful (0 votes)
5 views

Corejava Interview Booster 9

Uploaded by

tellapuri.naresh
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Corejava Interview Booster 9

Uploaded by

tellapuri.naresh
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 28

Interview Booster(21/09/2024)

=================================
In your code, you are currently using a `Predicate<Student>` to filter students
based on marks (`marks >= 60`). You want to extend this by using `Predicate` in the
if-else conditions.

Here’s an approach to modify your existing code so that each condition in your if-
else block is replaced by a `Predicate`:

### Steps:
1. **Create multiple predicates**: Each predicate will represent a condition, like
`marks >= 80`, `marks >= 60`, etc.
2. **Use `Predicate` for grading**: Each predicate will test the condition, and
based on that, you can assign the appropriate grade.

Here is a modified version of your code using `Predicate`:

```java
import java.util.function.*;

class Student {
String name;
int marks;

Student(String name, int marks) {


this.name = name;
this.marks = marks;
}
}

class Test {
public static void main(String[] args) {

// Define predicates for different grade ranges


Predicate<Student> distinction = s -> s.marks >= 80;
Predicate<Student> firstClass = s -> s.marks >= 60 && s.marks < 80;
Predicate<Student> secondClass = s -> s.marks >= 50 && s.marks < 60;
Predicate<Student> thirdClass = s -> s.marks >= 35 && s.marks < 50;
Predicate<Student> failed = s -> s.marks < 35;

// Function to apply grade based on predicates


Function<Student, String> f = s -> {
if (distinction.test(s)) return "A [Distinction]";
else if (firstClass.test(s)) return "B [FirstClass]";
else if (secondClass.test(s)) return "C [SecondClass]";
else if (thirdClass.test(s)) return "D [ThirdClass]";
else return "E [Failed]";
};

// Predicate to check passing marks (for example: 60)


Predicate<Student> passCondition = s -> s.marks >= 60;

Student[] students = {
new Student("Durga", 100),
new Student("Sunny", 65),
new Student("Bunny", 55),
new Student("Chinny", 45),
new Student("Vinny", 25)
};
for (Student s : students) {
if (passCondition.test(s)) {
System.out.println("Student Name: " + s.name);
System.out.println("Student Marks: " + s.marks);
System.out.println("Student Grade: " + f.apply(s));
System.out.println();
}
}
}
}
```

### Explanation:
- **Predicates**:
- `distinction`, `firstClass`, `secondClass`, `thirdClass`, and `failed` are
all predicates that test whether the student's marks fall within a specific range.
- **Function `f`**:
- The `Function<Student, String>` now uses these predicates to assign the
appropriate grade.
- **`passCondition`**:
- This predicate checks if the student has passed (`marks >= 60`) before
printing their details.

This approach modularizes the logic using predicates, making your code more
readable and functional. Let me know if you'd like further adjustments!
========================
In Java, **non-primitive data types** (also known as **reference types**) refer to
objects that are instances of classes. Unlike primitive data types (like `int`,
`char`, `boolean`), non-primitive data types store references to memory locations
where the actual objects are stored.

Here are some common examples of non-primitive data types in Java:

### 1. **Strings**
- **Description**: A `String` is a sequence of characters.
- **Example**:
```java
String name = "Java";
```

### 2. **Arrays**
- **Description**: Arrays are collections of elements of the same type.
- **Example**:
```java
int[] numbers = {1, 2, 3, 4, 5};
String[] names = {"Alice", "Bob", "Charlie"};
```

### 3. **Classes and Objects**


- **Description**: Objects are instances of user-defined classes.
- **Example**:
```java
class Car {
String brand;
int speed;
}

Car myCar = new Car();


```

### 4. **Interfaces**
- **Description**: Interfaces are abstract types used to specify behavior that
classes must implement.
- **Example**:
```java
interface Vehicle {
void start();
}

class Car implements Vehicle {


public void start() {
System.out.println("Car starting");
}
}

Vehicle myCar = new Car();


```

### 5. **Wrapper Classes**


- **Description**: These are classes that wrap around primitive types to provide
object-based functionality.
- **Example**:
```java
Integer age = 25; // Wrapper class for int
Boolean isAvailable = true; // Wrapper class for boolean
```

### 6. **Enums**
- **Description**: Enums are special classes that represent a fixed set of
constants.
- **Example**:
```java
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
}

Day today = Day.MONDAY;


```

### 7. **Collections (Lists, Sets, Maps, etc.)**


- **Description**: Collections are part of the Java Collections Framework and
include classes like `ArrayList`, `HashSet`, and `HashMap`.
- **Examples**:
- `List`:
```java
List<String> names = new ArrayList<>();
names.add("Alice");
```
- `Set`:
```java
Set<Integer> numbers = new HashSet<>();
numbers.add(10);
```
- `Map`:
```java
Map<String, Integer> map = new HashMap<>();
map.put("Alice", 30);
```

### 8. **Custom Data Types (User-defined Classes)**


- **Description**: You can create custom classes that define your own types.
- **Example**:
```java
class Person {
String name;
int age;

Person(String name, int age) {


this.name = name;
this.age = age;
}
}

Person person = new Person("Alice", 30);


```

These non-primitive types allow for more complex data structures and operations in
Java, providing much greater flexibility compared to primitive types.
==============================
A **functional interface** in Java is an interface that contains exactly one
abstract method. It is important for several reasons, especially when working with
lambda expressions and functional programming in Java.

### Reasons why Functional Interfaces are required:

1. **Enable Lambda Expressions:**


Functional interfaces are the foundation for using **lambda expressions**, which
provide a clear and concise way to implement a single-method interface. Instead of
creating an anonymous class, you can use a lambda expression to provide the
implementation of the abstract method in a functional interface.

Example:
```java
// Without Lambda Expression
Runnable r = new Runnable() {
public void run() {
System.out.println("Running without Lambda");
}
};

// With Lambda Expression


Runnable r = () -> System.out.println("Running with Lambda");
```

2. **Simplify Code:**
Functional interfaces, combined with lambda expressions, reduce boilerplate
code. Instead of writing multiple lines to define an anonymous class for a single
method interface, you can use a lambda expression, making the code more readable
and maintainable.

3. **Java Streams API:**


Functional interfaces are essential in the **Streams API**. Methods like
`filter()`, `map()`, and `forEach()` require functional interfaces, making it
easier to work with collections in a declarative style.

Example:
```java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
```

4. **Support Higher-Order Functions:**


Java supports **higher-order functions**, which means you can pass functions as
parameters to other functions. Functional interfaces allow you to represent these
functions as arguments, making Java more versatile in handling such cases.

5. **Encourage Functional Programming:**


Functional interfaces enable Java to support elements of **functional
programming**, which encourages writing side-effect-free, pure functions. This
allows for more predictable code behavior and easier reasoning about the code,
especially in concurrent or parallel environments.

6. **Built-in Functional Interfaces:**


Java provides several built-in functional interfaces (like `Function`,
`Consumer`, `Supplier`, `Predicate`) in the `java.util.function` package, which
help in a variety of programming tasks.

### Key Examples of Functional Interfaces:


- **Runnable**: Contains a single `run()` method.
- **Callable**: Contains a single `call()` method.
- **Comparator**: Contains the `compare()` method.

### @FunctionalInterface Annotation:


Java provides the `@FunctionalInterface` annotation to explicitly mark an interface
as functional. While this annotation is not mandatory, it helps prevent accidental
addition of more abstract methods to the interface, ensuring it remains functional.

In summary, functional interfaces in Java are important because they streamline


code, improve readability, and allow functional programming techniques such as
lambda expressions and method references, making Java more powerful and expressive.
==========================
You can use `System.out::println` as a method reference in Java where a functional
interface is expected, specifically for lambda expressions that match the method
signature of `System.out.println`. Here are some common use cases:

### 1. **In Streams**


When working with Java Streams, you can use `System.out::println` to print each
element of a collection:

```java
List<String> list = Arrays.asList("Apple", "Banana", "Cherry");
list.forEach(System.out::println);
```

### 2. **In Lambda Expressions**


Wherever a lambda expression is used, you can replace it with a method reference if
the method matches the expected signature:

```java
list.forEach(s -> System.out.println(s)); // This can be replaced by
list.forEach(System.out::println);
```
### 3. **In Event Handling (Functional Interfaces)**
You can use method references like `System.out::println` in event-driven
programming or with any functional interface that accepts a single argument:

```java
Runnable r = System.out::println;
r.run("Hello, World!"); // Prints "Hello, World!"
```

The use of `System.out::println` simplifies code by replacing verbose lambda


expressions when applicable.
=========================
Hibernate provides several annotations that are used to map Java classes to
database tables and manage persistence. Here are some of the most commonly used
annotations:

### Entity and Table Mapping

- **`@Entity`**: Marks a class as a Hibernate entity, which means it will be mapped


to a database table.
- **`@Table`**: Specifies the name of the database table to which the entity is
mapped. You can also define additional attributes like schema.

### Primary Key Mapping

- **`@Id`**: Specifies the primary key of the entity.


- **`@GeneratedValue`**: Indicates that the value of the primary key will be
generated automatically (e.g., using an identity or sequence strategy).
- **`@GenericGenerator`**: Allows you to define a custom primary key generation
strategy.

### Column Mapping

- **`@Column`**: Maps a field to a specific column in the table, allowing you to


specify attributes like name, length, nullable, etc.
- **`@Transient`**: Marks a field that should not be persisted in the database.

### Relationships

- **`@OneToOne`**: Defines a one-to-one relationship between two entities.


- **`@OneToMany`**: Defines a one-to-many relationship.
- **`@ManyToOne`**: Defines a many-to-one relationship.
- **`@ManyToMany`**: Defines a many-to-many relationship.
- **`@JoinColumn`**: Specifies the foreign key column used in a relationship.
- **`@JoinTable`**: Defines a join table for many-to-many relationships.

### Additional Annotations

- **`@Version`**: Used for optimistic locking by marking a version field in the


entity.
- **`@Embeddable`**: Marks a class whose instances can be embedded in other
entities.
- **`@Embedded`**: Indicates that an embeddable object should be included in the
entity.

### Example Usage

Here’s a simple example to illustrate some of these annotations:


```java
import javax.persistence.*;

@Entity
@Table(name = "users")
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "username", nullable = false, unique = true)


private String username;

@Column(name = "password")
private String password;

@Version
private int version;

// Getters and Setters


}
```

In this example:
- The `User` class is an entity mapped to the `users` table.
- The `id` field is the primary key and will be auto-generated.
- The `username` field is mapped to a column that cannot be null and must be
unique.
- The `version` field is used for optimistic locking.

These annotations provide a powerful way to define the structure of your database
in a way that is tightly integrated with your Java code.
=============================
In Hibernate, the `@GeneratedValue` annotation is used to specify how the primary
key value is generated for an entity. There are several strategies for generating
values, and you can also define custom strategies using `@GenericGenerator`. Here’s
a detailed explanation of the different generation strategies along with examples.

### 1. **Generation Strategies**

#### a. **AUTO**

- **Description**: Hibernate chooses the appropriate generation strategy for the


specific database.
- **Use Case**: Best when you want Hibernate to handle the generation logic for
you.

**Example**:
```java
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
```

#### b. **IDENTITY**

- **Description**: The database generates the primary key automatically when a new
record is inserted. This is common in databases that support auto-increment
columns.
- **Use Case**: Suitable for databases like MySQL.

**Example**:
```java
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
```

#### c. **SEQUENCE**

- **Description**: Uses a database sequence to generate primary key values. This


strategy is often used in databases like Oracle and PostgreSQL.
- **Use Case**: Useful when you need to generate unique keys that are independent
of the database operations.

**Example**:
```java
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq")
@SequenceGenerator(name = "user_seq", sequenceName = "user_sequence",
allocationSize = 1)
private Long id;
```

#### d. **TABLE**

- **Description**: Uses a separate table to generate primary key values. This


strategy can be used for compatibility with various databases.
- **Use Case**: Less common but useful for specific scenarios where other
strategies may not be feasible.

**Example**:
```java
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "user_gen")
@TableGenerator(name = "user_gen", table = "id_gen", pkColumnName = "gen_name",
valueColumnName = "gen_val", allocationSize = 1)
private Long id;
```

### 2. **Using @GenericGenerator**

The `@GenericGenerator` annotation allows you to define a custom primary key


generation strategy. This can be useful when you want to implement a specific logic
or integrate with external ID generation systems.

**Example**: Custom UUID Generation

```java
import org.hibernate.annotations.GenericGenerator;

@Entity
public class User {

@Id
@GeneratedValue(generator = "custom-uuid")
@GenericGenerator(name = "custom-uuid", strategy = "uuid2")
private String id;

private String username;

// Other fields, getters, and setters


}
```

### Explanation of Example:

1. **@GenericGenerator**:
- The `name` attribute defines the name of the generator ("custom-uuid").
- The `strategy` attribute specifies the generation strategy (`uuid2`), which
generates a UUID.

2. **@GeneratedValue**:
- Links the custom generator to the `id` field. This means whenever a new `User`
entity is persisted, a UUID will be generated for the `id`.

### Summary

- **AUTO**: Hibernate decides the best strategy.


- **IDENTITY**: Database generates the ID automatically.
- **SEQUENCE**: Utilizes a database sequence for ID generation.
- **TABLE**: Uses a separate table to manage ID generation.
- **GenericGenerator**: Allows for custom ID generation strategies like UUIDs or
other specific requirements.

Choosing the right generation strategy depends on your specific use case, database
capabilities, and application requirements.
=====================
The `@Temporal` annotation in Hibernate (and JPA) is used to specify how date and
time values should be mapped to the database. It is particularly important when
dealing with the `java.util.Date` or `java.util.Calendar` types.

### Usage of `@Temporal`

The `@Temporal` annotation can take one of three values:

1. **`TemporalType.DATE`**: Used for dates (year, month, day) without time


information.
2. **`TemporalType.TIME`**: Used for time (hours, minutes, seconds) without date
information.
3. **`TemporalType.TIMESTAMP`**: Used for both date and time (year, month, day,
hours, minutes, seconds).

### Example

Here’s how you can use the `@Temporal` annotation in a Hibernate entity class:

```java
import javax.persistence.*;
import java.util.Date;

@Entity
@Table(name = "events")
public class Event {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "event_name")
private String eventName;

@Temporal(TemporalType.DATE)
@Column(name = "event_date")
private Date eventDate;

@Temporal(TemporalType.TIME)
@Column(name = "event_time")
private Date eventTime;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "event_timestamp")
private Date eventTimestamp;

// Getters and Setters


}
```

### Explanation of the Example:

1. **Entity Class**: The `Event` class is marked as an entity with `@Entity` and is
mapped to the `events` table.

2. **Primary Key**: The `id` field is the primary key, generated automatically.

3. **Event Name**: The `eventName` field is a simple string representing the name
of the event.

4. **Event Date**:
- Annotated with `@Temporal(TemporalType.DATE)`, which means only the date part
(year, month, day) will be stored in the database. The time portion will be
ignored.

5. **Event Time**:
- Annotated with `@Temporal(TemporalType.TIME)`, meaning only the time (hours,
minutes, seconds) will be stored. The date part will be ignored.

6. **Event Timestamp**:
- Annotated with `@Temporal(TemporalType.TIMESTAMP)`, which stores both date and
time information.

### Database Mapping

Depending on the database being used, the fields would be mapped to the following
types:

- **`event_date`**: Date type in the database (e.g., `DATE` in MySQL).


- **`event_time`**: Time type in the database (e.g., `TIME` in MySQL).
- **`event_timestamp`**: Timestamp type in the database (e.g., `DATETIME` or
`TIMESTAMP` in MySQL).

### Summary

The `@Temporal` annotation is essential for correctly mapping date and time fields
in your entity classes to the appropriate database types. It helps ensure that you
store only the relevant parts of date and time as needed for your application.
===================
Got it! Let’s focus on how Hibernate interacts with database tables for creating
and updating them.

### 1. Creating a Table


When you define an entity class in Hibernate and annotate it properly, Hibernate
can automatically create the corresponding table in the database. This typically
occurs at startup if you have configured Hibernate to do so.

- **Entity Definition**: Define your entity class with appropriate JPA annotations.

```java
@Entity
@Table(name = "my_entity")
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

// Getters and setters


}
```

- **Configuration**: Set the Hibernate property to automatically create or update


the schema in your `hibernate.cfg.xml` or `application.properties`:

```properties
hibernate.hbm2ddl.auto=create
```

Options include:
- `create`: Drops existing tables and creates new ones.
- `update`: Updates the schema without dropping existing tables.
- `validate`: Validates the schema but does not make changes.
- `none`: No action.

### 2. Updating a Table


To update an existing table schema, such as adding a new column, you generally do
one of the following:

- **Modify the Entity**: Update your entity class by adding a new property.

```java
public class MyEntity {
// Existing fields...

private String newColumn; // New property

// Getters and setters


}
```

- **Hibernate Configuration**: Set the property to `update` in your configuration:

```properties
hibernate.hbm2ddl.auto=update
```

This will alter the existing table to include the new column when the application
starts.

### Summary
- **Table Creation**: Define an entity and set `hibernate.hbm2ddl.auto` to `create`
to have Hibernate generate the table.
- **Table Update**: Modify the entity class and set `hibernate.hbm2ddl.auto` to
`update` to apply changes to the existing table schema.

Make sure to backup your database before using `create` or `update` to prevent
unintended data loss!
=========================
To use a lambda expression with a `List<Employee>`, you typically want to perform
operations like filtering, mapping, or sorting. Here are some common examples using
Java's `Stream` API:

### Example Employee Class

First, let’s assume you have an `Employee` class defined as follows:

```java
public class Employee {
private String name;
private int age;
private double salary;

// Constructor, getters, and setters


public Employee(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}

public String getName() {


return name;
}

public int getAge() {


return age;
}

public double getSalary() {


return salary;
}
}
```

### 1. Filtering Employees

To filter employees by age (e.g., get employees older than 30):

```java
List<Employee> employees = // initialize your list here

List<Employee> filteredEmployees = employees.stream()


.filter(e -> e.getAge() > 30)
.collect(Collectors.toList());
```

### 2. Mapping Employees

To create a list of employee names:

```java
List<String> employeeNames = employees.stream()
.map(Employee::getName)
.collect(Collectors.toList());
```

### 3. Sorting Employees

To sort employees by salary in ascending order:

```java
List<Employee> sortedBySalary = employees.stream()
.sorted(Comparator.comparingDouble(Employee::getSalary))
.collect(Collectors.toList());
```

### 4. Calculating Total Salary

To calculate the total salary of all employees:

```java
double totalSalary = employees.stream()
.mapToDouble(Employee::getSalary)
.sum();
```

### 5. Checking Conditions

To check if there’s any employee with a salary above a certain amount:

```java
boolean hasHighSalary = employees.stream()
.anyMatch(e -> e.getSalary() > 100000);
```

### Summary

Lambda expressions provide a concise way to express operations on collections, such


as filtering, mapping, and reducing. By using the `Stream` API, you can leverage
these expressions to write cleaner and more expressive code for manipulating lists
of objects like `Employee`.
====================
Cascading in Hibernate refers to the mechanism of propagating certain operations
(like save, delete, etc.) from a parent entity to its associated child entities.
This is particularly useful when you want to manage related entities together,
ensuring that operations on the parent automatically apply to its children.

### Types of Cascading

1. **CascadeType.ALL**: Applies all cascade operations.


2. **CascadeType.PERSIST**: Propagates persist operations.
3. **CascadeType.MERGE**: Propagates merge operations.
4. **CascadeType.REMOVE**: Propagates remove operations.
5. **CascadeType.REFRESH**: Propagates refresh operations.
6. **CascadeType.DETACH**: Propagates detach operations.

### Example Scenario

Let’s consider a simple example with `Department` and `Employee` entities. A


department can have multiple employees.

### Entity Classes

**Department.java**

```java
import javax.persistence.*;
import java.util.Set;

@Entity
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

@OneToMany(mappedBy = "department", cascade = CascadeType.ALL, orphanRemoval =


true)
private Set<Employee> employees;

// Constructors, getters, and setters


public Department() {}

public Department(String name) {


this.name = name;
}

public void addEmployee(Employee employee) {


employees.add(employee);
employee.setDepartment(this);
}

// other getters and setters


}
```

**Employee.java**

```java
import javax.persistence.*;

@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

@ManyToOne
@JoinColumn(name = "department_id")
private Department department;

// Constructors, getters, and setters


public Employee() {}

public Employee(String name) {


this.name = name;
}

// other getters and setters


}
```

### Example Usage

Now, let’s see how cascading works in practice.

**Saving a Department with Employees**

```java
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

Department department = new Department("IT");

Employee emp1 = new Employee("John Doe");


Employee emp2 = new Employee("Jane Smith");

// Adding employees to the department


department.addEmployee(emp1);
department.addEmployee(emp2);

// Saving the department will also save the employees


session.save(department);

transaction.commit();
session.close();
```

In this case, when you save the `department`, both `emp1` and `emp2` will
automatically be saved due to the `CascadeType.ALL` setting on the `employees`
collection.

### Example of Deleting

If you want to delete a department and its employees, you can do the following:

```java
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

Department department = session.get(Department.class, departmentId);

// Deleting the department will also delete all associated employees


session.delete(department);

transaction.commit();
session.close();
```
### Orphan Removal

The `orphanRemoval = true` setting ensures that if an employee is removed from the
`employees` set, it will be deleted from the database:

```java
department.getEmployees().remove(emp1); // emp1 will be deleted from the database
```

### Summary

Cascading in Hibernate simplifies the management of related entities by allowing


operations on a parent entity to automatically propagate to child entities. This
reduces boilerplate code and helps maintain data integrity. When using cascading,
it’s essential to choose the cascade types that suit your application’s needs.
=======================
Hibernate Query Language (HQL) is an object-oriented query language used in
Hibernate, a popular Java framework for working with databases. HQL is similar to
SQL but operates on the entity objects rather than database tables. Here’s how it
works internally, along with examples.

### Key Concepts of HQL

1. **Object-Oriented**: HQL queries are written against the entity model rather
than the database schema. This allows developers to work with their domain model
directly.

2. **Entity-Based**: HQL treats entities as first-class citizens. You refer to them


by their class names instead of table names.

3. **Abstracted from SQL**: HQL abstracts away many of the complexities of SQL,
allowing you to focus more on the object model.

### How HQL Works Internally

1. **Parsing**: When you write an HQL query, Hibernate parses the query string to
understand its structure.

2. **Translation**: After parsing, HQL is translated into SQL. Hibernate generates


the appropriate SQL statements based on the underlying database and the entity
mappings.

3. **Execution**: The translated SQL is then executed against the database, and the
results are mapped back to entity objects.

4. **Result Handling**: The results returned by the database are converted back
into instances of your entity classes.

### Example Scenario

Let’s consider a simple example with two entities: `Author` and `Book`.

```java
@Entity
public class Author {
@Id
@GeneratedValue
private Long id;
private String name;

@OneToMany(mappedBy = "author")
private Set<Book> books;
}

@Entity
public class Book {
@Id
@GeneratedValue
private Long id;
private String title;

@ManyToOne
@JoinColumn(name = "author_id")
private Author author;
}
```

### HQL Example Queries

1. **Simple Select Query**

```java
String hql = "FROM Author";
Query query = session.createQuery(hql);
List<Author> authors = query.list();
```

**Explanation**:
- This query retrieves all `Author` entities.
- Internally, Hibernate translates this to a SQL statement like `SELECT * FROM
Author`.

2. **Using WHERE Clause**

```java
String hql = "FROM Book b WHERE b.author.name = :authorName";
Query query = session.createQuery(hql);
query.setParameter("authorName", "John Doe");
List<Book> books = query.list();
```

**Explanation**:
- This query retrieves all `Book` entities written by an author with the name "John
Doe".
- Hibernate translates it to an SQL query with a join, as it needs to fetch data
from both the `Book` and `Author` tables.

3. **Aggregating Results**

```java
String hql = "SELECT COUNT(b) FROM Book b";
Query query = session.createQuery(hql);
Long bookCount = (Long) query.uniqueResult();
```

**Explanation**:
- This query counts the number of `Book` entities.
- Hibernate constructs an SQL query like `SELECT COUNT(*) FROM Book`.

4. **Updating Data**

```java
String hql = "UPDATE Author a SET a.name = :newName WHERE a.id = :authorId";
Query query = session.createQuery(hql);
query.setParameter("newName", "Jane Doe");
query.setParameter("authorId", 1L);
int result = query.executeUpdate();
```

**Explanation**:
- This updates the name of the author with a specific ID.
- Hibernate translates this to an SQL update statement.

### Conclusion

HQL simplifies database interaction by allowing developers to query using their


object model. Its internal workings involve parsing, translation to SQL, execution,
and result mapping, making it a powerful tool in the Hibernate ecosystem. By
working with entities directly, HQL helps maintain a clean separation between the
database schema and the application logic.
===================
Criteria queries in Hibernate provide a programmatic way to build queries for
retrieving data from the database. Unlike HQL, which uses a string-based syntax,
Criteria queries use a fluent API that allows for more dynamic and flexible query
creation. This approach is particularly useful when building complex queries based
on user input or conditions that may vary at runtime.

### Key Features of Criteria Queries

1. **Type Safety**: Criteria queries are type-safe, meaning that they check for
correctness at compile time rather than runtime, reducing the likelihood of errors.

2. **Dynamic Queries**: You can build queries dynamically by adding criteria based
on user input or other conditions.

3. **Support for Projections**: You can specify which fields to return, allowing
you to retrieve only the data you need.

4. **Root Entities**: The root entity can be defined easily, allowing you to
navigate through associations.

### How to Use Criteria Queries

Here’s how to work with Criteria queries in Hibernate:

#### Example Scenario

Let’s continue with our previous example of `Author` and `Book` entities.

```java
@Entity
public class Author {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "author")
private Set<Book> books;
}

@Entity
public class Book {
@Id
@GeneratedValue
private Long id;
private String title;

@ManyToOne
@JoinColumn(name = "author_id")
private Author author;
}
```

### Example of Criteria Query

1. **Simple Criteria Query**

To retrieve all authors:

```java
Session session = sessionFactory.openSession();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<Author> criteriaQuery = criteriaBuilder.createQuery(Author.class);
Root<Author> root = criteriaQuery.from(Author.class);
criteriaQuery.select(root);

List<Author> authors = session.createQuery(criteriaQuery).getResultList();


session.close();
```

**Explanation**:
- `CriteriaBuilder` is used to create the `CriteriaQuery`.
- `Root` defines the root entity for the query.
- Finally, the query is executed, returning a list of `Author` entities.

2. **Criteria with WHERE Clause**

To filter authors by name:

```java
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<Author> criteriaQuery = criteriaBuilder.createQuery(Author.class);
Root<Author> root = criteriaQuery.from(Author.class);
criteriaQuery.select(root).where(criteriaBuilder.equal(root.get("name"), "John
Doe"));

List<Author> authors = session.createQuery(criteriaQuery).getResultList();


```

**Explanation**:
- `criteriaBuilder.equal` adds a condition to filter authors with the name "John
Doe".

3. **Criteria with Joins**


To fetch books by a specific author:

```java
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<Book> criteriaQuery = criteriaBuilder.createQuery(Book.class);
Root<Book> bookRoot = criteriaQuery.from(Book.class);
Join<Book, Author> authorJoin = bookRoot.join("author");

criteriaQuery.select(bookRoot).where(criteriaBuilder.equal(authorJoin.get("name"),
"John Doe"));

List<Book> books = session.createQuery(criteriaQuery).getResultList();


```

**Explanation**:
- `Join` is used to navigate from the `Book` entity to the `Author` entity.
- The query retrieves books written by "John Doe".

4. **Projection Queries**

To select specific fields, such as only the book titles:

```java
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<String> criteriaQuery = criteriaBuilder.createQuery(String.class);
Root<Book> bookRoot = criteriaQuery.from(Book.class);
criteriaQuery.select(bookRoot.get("title"));

List<String> bookTitles = session.createQuery(criteriaQuery).getResultList();


```

**Explanation**:
- The query selects only the `title` field from `Book`, returning a list of titles.

5. **Ordering Results**

To order the results by title:

```java
criteriaQuery.select(bookRoot).orderBy(criteriaBuilder.asc(bookRoot.get("title")));
List<Book> orderedBooks = session.createQuery(criteriaQuery).getResultList();
```

**Explanation**:
- The `orderBy` method specifies that the results should be ordered ascending by
the `title` field.

### Conclusion

Criteria queries in Hibernate provide a powerful and flexible way to construct


queries in a type-safe manner. They allow for dynamic query creation and can handle
complex scenarios with ease. By using the Criteria API, you can build queries that
adapt to various conditions, improving the robustness and maintainability of your
data access code.
==============================
To store a `double` salary as `NULL` in a database using Hibernate, you need to
ensure that the underlying database schema allows `NULL` values for the salary
column and that your entity class is correctly configured.
### Steps to Store a `double` Salary as `NULL`

1. **Database Schema**: Ensure that your database column for salary allows `NULL`
values. For example, in SQL, you would define your table like this:

```sql
CREATE TABLE Employee (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
salary DOUBLE NULL
);
```

2. **Entity Class Configuration**: In your entity class, you can define the
`salary` field as `Double` (the wrapper class) instead of `double` (the primitive
type). This allows the salary to be `null`.

```java
@Entity
public class Employee {
@Id
@GeneratedValue
private Long id;
private String name;
private Double salary; // Use Double instead of double

// Getters and Setters


}
```

3. **Setting Salary to Null**: When creating or updating an `Employee`, you can set
the salary to `null` as needed.

```java
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

Employee employee = new Employee();


employee.setName("John Doe");
employee.setSalary(null); // Setting salary to null

session.save(employee);
transaction.commit();
session.close();
```

### Example of Handling Salary as `NULL`

Here's a complete example demonstrating how to save an employee with a `NULL`


salary:

```java
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

@Entity
public class Employee {
@Id
@GeneratedValue
private Long id;
private String name;
private Double salary; // Wrapper class to allow null

// Getters and Setters


}

// Main class to demonstrate saving an employee


public class Main {
public static void main(String[] args) {
SessionFactory sessionFactory = new
Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

Employee employee = new Employee();


employee.setName("John Doe");
employee.setSalary(null); // Setting salary to null

session.save(employee);
transaction.commit();
session.close();
sessionFactory.close();
}
}
```

### Summary

1. **Use `Double` instead of `double`**: This allows you to set the salary to
`null`.
2. **Ensure database column allows `NULL`**: Define your database schema to accept
`NULL` values.
3. **Set the salary to `null`**: When creating or updating the entity, you can
explicitly set the salary to `null`.

This approach will enable you to store a `NULL` salary in your database correctly.
===================
Hibernate provides a powerful caching mechanism to improve performance by reducing
the number of database queries. There are two primary levels of caching in
Hibernate: **First-Level Cache** and **Second-Level Cache**. Additionally, there is
a **Query Cache** that can be used in conjunction with the second-level cache.
Let’s explore each level in detail.

### 1. First-Level Cache

- **Definition**: The first-level cache is the session cache, which is associated


with the Hibernate `Session` object. It is enabled by default and exists for the
duration of the session.
- **Scope**: Each session has its own first-level cache. Data stored in this cache
is not shared across sessions.

**Example**:
```java
Session session1 = sessionFactory.openSession();
Transaction transaction1 = session1.beginTransaction();
// Fetching an entity
Author author1 = session1.get(Author.class, 1L); // Hits the database
Author author2 = session1.get(Author.class, 1L); // Hits the first-level cache

transaction1.commit();
session1.close();
```

**Explanation**:
- The first `get()` call fetches the `Author` entity from the database.
- The second `get()` call retrieves the same entity from the first-level cache,
avoiding a second database hit.

### 2. Second-Level Cache

- **Definition**: The second-level cache is an optional cache that is shared across


sessions. It allows for caching of entities, collections, and query results beyond
the life of a single session.
- **Configuration**: You need to explicitly enable and configure it in your
Hibernate configuration file.

**Example Configuration**:
```xml
<property name="hibernate.cache.use_second_level_cache">true</property>
<property
name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegi
onFactory</property>
```

**Using Second-Level Cache**:


```java
@Entity
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Author {
@Id
@GeneratedValue
private Long id;
private String name;

// Getters and Setters


}

// Usage
Session session1 = sessionFactory.openSession();
Author author1 = session1.get(Author.class, 1L); // Hits the database
session1.close();

Session session2 = sessionFactory.openSession();


Author author2 = session2.get(Author.class, 1L); // Hits the second-level cache
session2.close();
```

**Explanation**:
- The first session fetches the `Author` from the database.
- The second session retrieves the same `Author` from the second-level cache,
avoiding a database hit.
### 3. Query Cache

- **Definition**: The query cache stores the results of a query and can be used in
conjunction with the second-level cache to cache the results of HQL or Criteria
queries.
- **Configuration**: It must be enabled in the Hibernate configuration.

**Example Configuration**:
```xml
<property name="hibernate.cache.use_query_cache">true</property>
```

**Using Query Cache**:


```java
String hql = "FROM Author a WHERE a.name = :name";
Query query = session.createQuery(hql);
query.setParameter("name", "John Doe");
query.setCacheable(true); // Enable query caching
List<Author> authors = query.list(); // Hits the database

// Subsequent call with the same parameters will hit the query cache
List<Author> cachedAuthors = query.list(); // Hits the query cache
```

**Explanation**:
- The first query execution fetches data from the database.
- Subsequent executions of the same query with the same parameters retrieve the
results from the query cache.

### Summary of Cache Levels

1. **First-Level Cache**:
- Session-scoped
- Enabled by default
- Not shared across sessions

2. **Second-Level Cache**:
- Session-factory scoped
- Optional and configurable
- Shared across sessions

3. **Query Cache**:
- Caches query results
- Works in conjunction with the second-level cache

### Conclusion

Using caching effectively in Hibernate can significantly improve application


performance by reducing database access. The first-level cache provides a quick
access layer during a session, while the second-level cache and query cache allow
for shared caching across sessions, optimizing repeated data access patterns.
=================
Container engines are platforms that enable containerization by allowing the
creation, running, and management of containers. Below are some popular examples of
container engines:

### 1. **Docker**
- **Description**: The most popular and widely used container engine that allows
developers to package applications with all their dependencies into a container. It
is known for its simplicity and efficiency.
- **Use Cases**: Development, testing, continuous integration, and deployment of
applications.

### 2. **Podman**
- **Description**: A daemon-less container engine for developing, managing, and
running OCI containers. It is compatible with Docker but does not require a running
daemon.
- **Use Cases**: Run containers without the need for a background service or
daemon, making it ideal for system-level containerization.

### 3. **CRI-O**
- **Description**: A lightweight container engine designed specifically to run
Kubernetes pods. It is an implementation of Kubernetes Container Runtime Interface
(CRI).
- **Use Cases**: Running containers as part of Kubernetes clusters with minimal
overhead.

### 4. **containerd**
- **Description**: An industry-standard core container runtime that is used as
an underlying engine for Docker. It focuses on simplicity and portability.
- **Use Cases**: Efficient container management in a production environment,
Kubernetes runtime integration.

### 5. **LXC (Linux Containers)**


- **Description**: A Linux-based containerization solution that provides OS-
level virtualization. It uses Linux control groups (cgroups) and namespaces to
isolate processes.
- **Use Cases**: System containerization, running multiple Linux distributions
on a single system.

### 6. **rkt (Rocket)**


- **Description**: Developed by CoreOS, rkt is an application container engine
designed for security and modularity. It integrates tightly with systemd and is
optimized for running containerized apps.
- **Use Cases**: Running secure and isolated container workloads, especially in
CoreOS environments.

### 7. **Kata Containers**


- **Description**: A lightweight container runtime that provides the security of
VMs with the speed of containers by using hardware virtualization technology.
- **Use Cases**: Running secure containers with better isolation, combining the
advantages of both containers and virtual machines.

These container engines have different features and are suited for different use
cases, ranging from lightweight development environments to heavy-duty production
deployments.
=================
Here are the steps and commands for deploying an application to Docker Hub:

### Prerequisites:
1. **Install Docker** on your machine:
- Follow the official guide to install Docker on
[Ubuntu](https://docs.docker.com/engine/install/ubuntu/) or
[Windows](https://docs.docker.com/desktop/windows/install/).
2. **Create a Docker Hub account**:
- Go to [Docker Hub](https://hub.docker.com/) and create an account if you don't
have one.
---

### Step-by-Step Deployment to Docker Hub:

#### 1. **Create Your Dockerfile**


You need a `Dockerfile` in your project directory that contains instructions on how
to build your application’s image.

```Dockerfile
# Example Dockerfile
FROM ubuntu:latest # Use the base image (e.g., ubuntu)
WORKDIR /app # Set working directory

COPY . /app # Copy all project files to /app directory in container

RUN apt-get update && apt-get install -y python3

CMD ["python3", "app.py"] # The command to run the application


```

- Make sure you adjust the `Dockerfile` according to your app requirements (e.g.,
if it's a Java or Node.js app).

#### 2. **Build the Docker Image**


Navigate to your application folder that contains the `Dockerfile` and build your
Docker image.

```bash
docker build -t <docker-username>/<image-name>:<tag> .
```

For example:
```bash
docker build -t naresh/my-app:1.0 .
```

This command will build the image with the name `my-app` and the tag `1.0` for user
`naresh`.

#### 3. **Test the Docker Image Locally**


Run the Docker image locally to verify it works before pushing it to Docker Hub.

```bash
docker run -p 8080:8080 <docker-username>/<image-name>:<tag>
```

For example:
```bash
docker run -p 8080:8080 naresh/my-app:1.0
```

This will run your app locally, and you can test it by going to
`http://localhost:8080` in your browser (adjust the port based on your app).

#### 4. **Log in to Docker Hub**


Login to Docker Hub from your terminal:

```bash
docker login
```

- Enter your Docker Hub username and password when prompted.

#### 5. **Tag Your Image**


If your image is not already tagged with your Docker Hub username, you need to tag
it with the correct repository name before pushing:

```bash
docker tag <image-id> <docker-username>/<image-name>:<tag>
```

For example:
```bash
docker tag my-app:1.0 naresh/my-app:1.0
```

#### 6. **Push Your Image to Docker Hub**


Now push your Docker image to Docker Hub using:

```bash
docker push <docker-username>/<image-name>:<tag>
```

For example:
```bash
docker push naresh/my-app:1.0
```

Docker will upload your image to Docker Hub.

#### 7. **Verify on Docker Hub**


Go to [Docker Hub](https://hub.docker.com/) and check your repository. You should
see the image you just pushed.

---

### Example Workflow:

```bash
# Step 1: Build the Docker image
docker build -t naresh/my-app:1.0 .

# Step 2: Run the Docker image locally


docker run -p 8080:8080 naresh/my-app:1.0

# Step 3: Log in to Docker Hub


docker login

# Step 4: Tag the Docker image (if needed)


docker tag my-app:1.0 naresh/my-app:1.0

# Step 5: Push the Docker image to Docker Hub


docker push naresh/my-app:1.0
```

### Notes:
- Replace `<docker-username>` with your Docker Hub username.
- Replace `<image-name>` with the name of your image.
- Replace `<tag>` with the version or tag you want to use for the image.

This process will deploy your application in Docker Hub, and it can be pulled and
run by others using:

```bash
docker pull <docker-username>/<image-name>:<tag>
docker run -p 8080:8080 <docker-username>/<image-name>:<tag>
```
=============================================================** END
**=================================================================================
===========

You might also like