javax.faces.el.EvaluationException: java.lang.NullPointerException

Olá pessoal, estou recebendo o erro “javax.faces.el.EvaluationException: java.lang.NullPointerException” e não estou conseguindo identificar o erro.
Meu bean:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.guiatv.bean;

import br.com.guiatv.dao.CanalDAO;
import br.com.guiatv.dao.ProgramaDAO;
import br.com.guiatv.entity.Canal;
import br.com.guiatv.entity.Programa;
import java.util.List;
import java.io.Serializable;
import java.util.Objects;
import javax.annotation.ManagedBean;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

/**
 *
 * @author Tauan
 */
@ManagedBean
@SessionScoped
@Named(value = "controleTvBean")
public class GuiaBean implements Serializable {

    public GuiaBean() {
    }

    Canal canal = new Canal();
    CanalDAO canalDAO = new CanalDAO();
    private Programa programa = new Programa();
    ProgramaDAO programaDAO = new ProgramaDAO();

    public void salvarCanal() {
        canalDAO.cadastrarCanal(canal);
        canal.setNome(null);
    }

    public void salvarPrograma() {
        programaDAO.cadastrarPrograma(programa);
        programa.setNome(null);
        programa.setHorario(null);
        programa.setDia_semana(null);
    }
    
    public List<Canal> pegarCanais(){
        return canalDAO.getAllCanais();
    }

    public Canal getCanal() {
        return canal;
    }

    public void setCanal(Canal canal) {
        this.canal = canal;
    }

    public Programa getPrograma() {
        return programa;
    }

    public void setPrograma(Programa programa) {
        this.programa = programa;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 29 * hash + Objects.hashCode(this.canal);
        hash = 29 * hash + Objects.hashCode(this.programa);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final GuiaBean other = (GuiaBean) obj;
        if (!Objects.equals(this.canal, other.canal)) {
            return false;
        }
        if (!Objects.equals(this.programa, other.programa)) {
            return false;
        }
        return true;
    }
    
    

}

Meu ProgramaDAO:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.guiatv.dao;

import br.com.guiatv.entity.Canal;
import br.com.guiatv.entity.Programa;
import javax.persistence.*;
/**
 *
 * @author Tauan
 */
public class ProgramaDAO {
    
    public void cadastrarPrograma(Programa novoPrograma){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("guiatvhibernate");
        EntityManager em = emf.createEntityManager();
        Programa p = new Programa();
        p.setNome(novoPrograma.getNome());
        p.setHorario(novoPrograma.getHorario());
        p.setDia_semana(novoPrograma.getDia_semana());
        p.getCanal().setEstacao(novoPrograma.getCanal().getEstacao());
        em.getTransaction().begin(); 
        em.persist(p);
        em.getTransaction().commit();
        em.close();
        emf.close();
    }
}

Meu CanalDAO:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.guiatv.dao;

import br.com.guiatv.entity.Canal;
import java.util.List;
import javax.persistence.*;
import net.sf.ehcache.search.expression.Criteria;

/**
 *
 * @author Tauan
 */
public class CanalDAO {
    
    public List<Canal> listaCanais;
    
    public void cadastrarCanal(Canal novoCanal){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("guiatvhibernate"); 
        EntityManager em = emf.createEntityManager();
        Canal c = new Canal();
        c.setEstacao(novoCanal.getEstacao());
        c.setNome(novoCanal.getNome());
        em.getTransaction().begin();
        em.persist(c);
        em.getTransaction().commit();
        em.close();
        emf.close();
    }
    public List<Canal> getAllCanais(){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("guiatvhibernate"); 
        EntityManager em = emf.createEntityManager();
         TypedQuery<Canal> query = em.createQuery("SELECT c FROM Canal AS c", Canal.class);
        listaCanais = query.getResultList();
        
        for(Canal c : listaCanais){
            System.out.println("Nome: " + c.getNome());
            System.out.println("Estação" + c.getEstacao());
        }
        return listaCanais;
    }
}

Minha entity Canal:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.guiatv.entity;

import java.io.Serializable;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.*;

/**
 *
 * @author Tauan
 */
@Entity
@Table(name = "tb_canal")
public class Canal implements Serializable{
    

    @NotNull(message = "A estação não pode ser nula")
    @Id
    @Column(name = "can_estacao")
    private int estacao;
    
    @Length(max = 50, message = "O nome do canal não pode ter mais de {max} caracteres!")
    @NotBlank(message = "O nome do canal não poder estar em branco")
    @NotNull(message = "O nome do canal não pode ser nulo")
    @Column(name = "can_nome", length = 25, nullable = false)
    private String nome;

    public int getEstacao() {
        return estacao;
    }

    public void setEstacao(int estacao) {
        this.estacao = estacao;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 59 * hash + this.estacao;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Canal other = (Canal) obj;
        if (this.estacao != other.estacao) {
            return false;
        }
        return true;
    }

    
   
}

Minha entity Programa:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.guiatv.entity;

import java.io.Serializable;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;

/**
 *
 * @author Tauan
 */
@Entity
@Table(name = "tb_programa")
public class Programa implements Serializable{
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    
    @Length(max = 25, message = "O nome do programa não pode ter mais de {max} caracteres!")
    @NotBlank(message = "O nome do programa não poder estar em branco")
    @NotNull(message = "O nome do programa não pode ser nulo")
    @Column(name = "prog_nome", length = 25, nullable = false)
    private String nome;
    
    @Length(max = 5, message = "O horário do programa não pode ter mais de {max} caracteres!")
    @NotBlank(message = "O horário do programa não poder estar em branco")
    @NotNull(message = "O horário do programa não pode ser nulo")
    @Column(name = "prog_horario", length = 5, nullable = false)
    private String horario;
    
    @Length(max = 25, message = "O dia do programa não pode ter mais de {max} caracteres!")
    @NotBlank(message = "O dia do programa não poder estar em branco")
    @NotNull(message = "O dia do programa não pode ser nulo")
    @Column(name = "prog_dia", length = 25, nullable = false)
    private String dia_semana;
    
    @NotNull(message = "O canal deve ser informado")
    @ManyToOne
    @JoinColumn(name = "prog_canal", referencedColumnName = "can_estacao", nullable = false)
    private Canal canal;
    
    

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getHorario() {
        return horario;
    }

    public void setHorario(String horario) {
        this.horario = horario;
    }

    public String getDia_semana() {
        return dia_semana;
    }

    public void setDia_semana(String dia_semana) {
        this.dia_semana = dia_semana;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 59 * hash + this.id;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Programa other = (Programa) obj;
        if (this.id != other.id) {
            return false;
        }
        return true;
    }

    public Canal getCanal() {
        return canal;
    }

    public void setCanal(Canal canal) {
        this.canal = canal;
    }
    
    
    
    
}

Meu persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence          http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="guiatvhibernate">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class/>
    <class>br.com.guiatv.entity.Canal</class>
    <class>br.com.guiatv.entity.Programa</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.SingletonEhCacheProvider"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.format_sql" value="true"/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/guiahibernate"/>
      <property name="javax.persistence.jdbc.user" value="root"/>
      <property name="javax.persistence.jdbc.password" value=""/>
    </properties>
  </persistence-unit>
</persistence>

Meu index.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://xmlns.jcp.org/jsf/passthrough"
      xmlns:jsf="http://xmlns.jcp.org/jsf"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <script src="js/main.js"></script>
    <h:head>
        <title>GuiaTv</title>
    </h:head>
    <h:body>
        <h1>Guia de TV</h1>
        <h:form>
            <h2>Cadastro de Canal</h2>
            <label for="nome">Nome do canal</label><br/>
            <h:inputText id="nomeCanalTXT" value="#{controleTvBean.canal.nome}"/> <br/>
            <label for="estacao">Estação do canal</label><br/>
            <h:inputText id="estacaoCanalTXT" value="#{controleTvBean.canal.estacao}"/><br/>
            <h:commandButton value="Cadastrar Canal" action="#{controleTvBean.salvarCanal}"/> 
        </h:form>
        <h:form>
            <h2>Cadastro de Programa</h2>
            <label>Nome do programa</label><br/>
            <h:inputText id="nomeProgramaTXT" value="#{controleTvBean.programa.nome}"/><br/>
            <label>Horário do Programa</label><br/>
            <input id="horarioProgramaTXT" type="time"  jsf:value="#{controleTvBean.programa.horario}"/><br/>
            <label>Dia do Programa</label><br/>
            <h:selectOneMenu class="form-control" required="true" id="dia_semana" value="#{controleTvBean.programa.dia_semana}">
                <f:selectItem itemLabel="Selecione o dia" noSelectionOption="true"/>
                <f:selectItem itemValue="Domingo" itemLabel="Domingo" />
                <f:selectItem itemValue="Segunda-feira" itemLabel="Segunda-feira" />
                <f:selectItem itemValue="Terça-feira" itemLabel="Terça-feira" />
                <f:selectItem itemValue="Quarta-feira" itemLabel="Quarta-feira" />
                <f:selectItem itemValue="Quinta-feira" itemLabel="Quinta-feira" />
                <f:selectItem itemValue="Sexta-feira" itemLabel="Sexta-feira" />
                <f:selectItem itemValue="Sábado" itemLabel="Sábado" />
            </h:selectOneMenu><br/>
             <label>Canal do Programa</label><br/>
             <h:selectOneMenu required="true" class="form-control" id="canal"  >
                                            <f:selectItem itemLabel="Selecione o canal" noSelectionOption="true"/>
                                            <f:selectItems value="#{controleTvBean.pegarCanais()}" var="canal" 
                                                           itemValue="#{canal.estacao}" 
                                                           itemLabel="#{canal.nome}" />
                                        </h:selectOneMenu>

            <h:commandButton value="Cadastrar Programa" action="#{controleTvBean.salvarPrograma()}"/> 
        </h:form>



    </h:body>
</html>

Meu StackTrace:

javax.faces.el.EvaluationException: java.lang.NullPointerException
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
	at javax.faces.component.UICommand.broadcast(UICommand.java:315)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
	at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
	at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
	at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
	at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
	at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
	at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
	at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
	at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
	at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
	at br.com.guiatv.dao.ProgramaDAO.cadastrarPrograma(ProgramaDAO.java:24)
	at br.com.guiatv.bean.GuiaBean.salvarPrograma(GuiaBean.java:42)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at javax.el.ELUtil.invokeMethod(ELUtil.java:332)
	at javax.el.BeanELResolver.invoke(BeanELResolver.java:537)
	at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
	at com.sun.el.parser.AstValue.invoke(AstValue.java:283)
	at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
	at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
	at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
	at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
	... 36 more

Como podem ver, ele aponta o erro para as funções

br.com.guiatv.dao.ProgramaDAO.cadastrarPrograma(ProgramaDAO.java:24) br.com.guiatv.bean.GuiaBean.salvarPrograma(GuiaBean.java:42)

Mas não consigo identificar qual é o erro. Desde já obrigado.

Se o que está nesta linha at br.com.guiatv.dao.ProgramaDAO.cadastrarPrograma(ProgramaDAO.java:24)
é isso em.getTransaction().commit();, significa que a transaction não foi instanciada
em.beginTransaction(); deve resolver.
Caso não seja, o que está na linha 24 do ProgramaDAO.java?